Differences From Artifact [9d008566c9]:

To Artifact [40c0c39483]:


78
79
80
81
82
83
84






85
86
87
88
89
90
91
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
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__ = [
    "get_data", "module_list", "plugin_meta", "add_plugin_defaults"
    "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
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
        Read literal files, or .pyz contents.
    src : str
        from already uncovered script code
        From already uncovered script code.
    module : str
        lookup per pkgutil, from plugin_base or top-level modules
        Lookup per pkgutil, from plugin_base or top-level modules.
    frame : int
        extract comment header of caller (default)
        Extract comment header of caller (default).
    extra_base : list
        additional search directories
        Additional search directories.
    max_length : list
        maximum size to read from files
        Maximum size to read from files.

    Returns
    -------
    dict : key-value pairs of comment fields, config: preparsed
    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
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.
    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
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("-", "_")] = field[1].strip()
        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, convenience dict with property access """
    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)
        return self.get(key, "")

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


# Unpack config: structures