Differences From Artifact [9d008566c9]:

To Artifact [40c0c39483]:


78
79
80
81
82
83
84






85
86
87
88
89
90
91
#
# Using a plugin_state config dictionary in most cases can just list
# module basenames, if there's only one namespace to manage. (Plugin
# names unique across project.)

"""
Plugin meta extraction and module lookup







![#](https://fossil.include-once.org/pluginspec/logo)
"""


import sys
import os







>
>
>
>
>
>







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#
# Using a plugin_state config dictionary in most cases can just list
# module basenames, if there's only one namespace to manage. (Plugin
# names unique across project.)

"""
Plugin meta extraction and module lookup

 * Main function `plugin_meta(filename=…)` unpacks
   [meta fields](https://fossil.include-once.org/pluginspec/)
   into dictionaries.
 * Other utility code is about module location, but requires
   some initialization.

![#](https://fossil.include-once.org/pluginspec/logo)
"""


import sys
import os
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
        def gzip_decode(bytestr):
            """ haphazard workaround """
            return zlib.decompress(bytestr, 16 + zlib.MAX_WBITS)
import zipfile
import argparse

__all__ = [
    "get_data", "module_list", "plugin_meta", "add_plugin_defaults"

]


# Injectables
# ‾‾‾‾‾‾‾‾‾‾‾
""" injectable callback function for logging """
log_ERR = lambda *x: None







|
>







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
        def gzip_decode(bytestr):
            """ haphazard workaround """
            return zlib.decompress(bytestr, 16 + zlib.MAX_WBITS)
import zipfile
import argparse

__all__ = [
    "plugin_meta", "get_data", "module_list", "add_plugin_defaults",
    "PluginMeta", "all_plugin_meta",
]


# Injectables
# ‾‾‾‾‾‾‾‾‾‾‾
""" injectable callback function for logging """
log_ERR = lambda *x: None
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
def plugin_meta(filename=None, src=None, module=None, frame=1, **kwargs):
    """
    Extract plugin meta data block from different sources:

    Parameters
    ----------
    filename : str
        read literal files, or .pyz contents
    src : str
        from already uncovered script code
    module : str
        lookup per pkgutil, from plugin_base or top-level modules
    frame : int
        extract comment header of caller (default)
    extra_base : list
        additional search directories
    max_length : list
        maximum size to read from files

    Returns
    -------
    dict : key-value pairs of comment fields, config: preparsed
    """

    # Try via pkgutil first,
    # find any plugins.* modules, or main packages
    if module:
        filename = module
        for base in plugin_base + kwargs.get("extra_base", []):







|

|

|

|

|

|



|







256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
def plugin_meta(filename=None, src=None, module=None, frame=1, **kwargs):
    """
    Extract plugin meta data block from different sources:

    Parameters
    ----------
    filename : str
        Read literal files, or .pyz contents.
    src : str
        From already uncovered script code.
    module : str
        Lookup per pkgutil, from plugin_base or top-level modules.
    frame : int
        Extract comment header of caller (default).
    extra_base : list
        Additional search directories.
    max_length : list
        Maximum size to read from files.

    Returns
    -------
    dict : Extracted comment fields, with config: preparsed
    """

    # Try via pkgutil first,
    # find any plugins.* modules, or main packages
    if module:
        filename = module
        for base in plugin_base + kwargs.get("extra_base", []):
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# Comment and field extraction logic
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
@renamed_arguments({"fn": "filename"})
def plugin_meta_extract(src="", filename=None, literal=False):
    """
    Finds the first comment block. Splits key:value header
    fields from comment. Turns everything into an dict, with
    some stub fields if absent.

    Parameters
    ----------
    src : str
        from existing source code
    filename : str
        set filename attribute







|







319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# Comment and field extraction logic
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
@renamed_arguments({"fn": "filename"})
def plugin_meta_extract(src="", filename=None, literal=False):
    """
    Finds the first comment block. Splits key:value header
    fields from comment. Turns everything into an dict, with
    some stub fields if absent. Dashes substituted for underscores.

    Parameters
    ----------
    src : str
        from existing source code
    filename : str
        set filename attribute
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370

371



372
373
374
375
376
377
378
379
380
381
382

    # Split comment block
    if src.find("\n\n") > 0:
        src, meta["doc"] = src.split("\n\n", 1)

    # Turn key:value lines into dictionary
    for field in rx.keyval.findall(src):
        meta[field[0].replace("-", "_")] = field[1].strip()
    meta["config"] = plugin_meta_config(meta.get("config") or "")

    return PluginMeta(meta)


# Dict wrapper
# ‾‾‾‾‾‾‾‾‾‾‾‾
class PluginMeta(dict):

    """ Plugin meta data, convenience dict with property access """




    def __getattr__(self, key):
        """ Return [key] for .property access, else None """
        return self.get(key)

    def __hasattr__(self, key):
        """ Return [key] for .property access, else None """
        return key in self


# Unpack config: structures







|








>
|
>
>
>



|







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393

    # Split comment block
    if src.find("\n\n") > 0:
        src, meta["doc"] = src.split("\n\n", 1)

    # Turn key:value lines into dictionary
    for field in rx.keyval.findall(src):
        meta[field[0].replace("-", "_").lower()] = field[1].strip()
    meta["config"] = plugin_meta_config(meta.get("config") or "")

    return PluginMeta(meta)


# Dict wrapper
# ‾‾‾‾‾‾‾‾‾‾‾‾
class PluginMeta(dict):
    """
    Plugin meta data, as dictionary with alternative .property access.
    Returned for each `plugin_meta()` result, and config: options.
    Non-existent .fieldnames just resolve to `""`.
    """

    def __getattr__(self, key):
        """ Return [key] for .property access, else None """
        return self.get(key, "")

    def __hasattr__(self, key):
        """ Return [key] for .property access, else None """
        return key in self


# Unpack config: structures