Differences From Artifact [1b5dd2ab14]:

To Artifact [b93e156971]:


292
293
294
295
296
297
298
299

300
301
302
303
304
305
306


307


308
309
310
311
312
313
314
        search = plugin_base + kwargs.get("extra_base", [])
        for base, sfx in itertools.product(search, [".py", "/__init__.py"]):
            try:
                #log.debug(f"mod={base} fn={filename}.py")
                src = get_data(filename=module+sfx, decode=True, file_root=base, warn=False)
                if src:
                    break
            except (IOError, OSError, FileNotFoundError):

                continue  # plugin_meta_extract() will print a notice later
        else:
            log.warning("Found no source candidate for '%s'", module)
        filename = module

    # Real filename/path
    elif filename and os.path.exists(filename):


        src = open(filename).read(kwargs.get("max_length", 6144))



    # Else get source directly from caller
    elif not src and not filename:
        module = inspect.getmodule(sys._getframe(frame+1)) # decorator+1
        filename = inspect.getsourcefile(module)
        src = inspect.getcomments(module)








|
>







>
>
|
>
>







292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
        search = plugin_base + kwargs.get("extra_base", [])
        for base, sfx in itertools.product(search, [".py", "/__init__.py"]):
            try:
                #log.debug(f"mod={base} fn={filename}.py")
                src = get_data(filename=module+sfx, decode=True, file_root=base, warn=False)
                if src:
                    break
            except (IOError, OSError, FileNotFoundError, UnicodeDecodeError) as exc:
                log.debug("base=%s module=%s sfx=%s, exception=%s", base, module, sfx, exc)
                continue  # plugin_meta_extract() will print a notice later
        else:
            log.warning("Found no source candidate for '%s'", module)
        filename = module

    # Real filename/path
    elif filename and os.path.exists(filename):
        try:
            with open(filename, "r", encoding="utf-8") as read:
                src = read.read(kwargs.get("max_length", 6144))
        except UnicodeDecodeError as exc:
            log.error("read/decode error %s for %s", exc, filename)

    # Else get source directly from caller
    elif not src and not filename:
        module = inspect.getmodule(sys._getframe(frame+1)) # decorator+1
        filename = inspect.getsourcefile(module)
        src = inspect.getcomments(module)

346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
    | src         | str     | from existing source code       |
    | filename    | str     | set filename attribute          |
    | literal     | bool    | just split comment from doc     |
    | **Returns** | dict    | fields                          |
    """

    # Defaults
    meta = {
        "id": os.path.splitext(os.path.basename(filename or ""))[0],
        "fn": filename,
        "api": "python",
        "type": "module",
        "category": None,
        "priority": None,
        "version": "0",
        "title": filename,
        "description": "no description",
        "config": [],
        "doc": ""
    }

    # Extract coherent comment block
    src = src.replace("\r", "")
    if not literal:
        src = rx.header.sub("", src)
        src = rx.comment.search(src)
        if not src:







|











|







351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
    | src         | str     | from existing source code       |
    | filename    | str     | set filename attribute          |
    | literal     | bool    | just split comment from doc     |
    | **Returns** | dict    | fields                          |
    """

    # Defaults
    meta = PluginMeta({
        "id": os.path.splitext(os.path.basename(filename or ""))[0],
        "fn": filename,
        "api": "python",
        "type": "module",
        "category": None,
        "priority": None,
        "version": "0",
        "title": filename,
        "description": "no description",
        "config": [],
        "doc": ""
    })

    # Extract coherent comment block
    src = src.replace("\r", "")
    if not literal:
        src = rx.header.sub("", src)
        src = rx.comment.search(src)
        if not src:
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
        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/list wrappers
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
class PluginMeta(dict):
    """
    Plugin meta data as dictionary`{}`, or alternatively `.property` access.







|







385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
        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 meta


# Dict/list wrappers
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
class PluginMeta(dict):
    """
    Plugin meta data as dictionary`{}`, or alternatively `.property` access.