Overview
Comment:predefine conf[plugins], note .base(__package__) as example
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 94218baefa5b84533ea19fba16bb5dbb380bdb8545ba8257325e655730dd0290
User & Date: mario on 2022-11-01 23:30:00
Other Links: manifest | tags
Context
2022-11-01
23:30
shift warning for undiscoverable modules check-in: 18c5918a6d user: mario tags: trunk
23:30
predefine conf[plugins], note .base(__package__) as example check-in: 94218baefa user: mario tags: trunk
23:29
use dict.pop() instead of get+del check-in: 900b323b25 user: mario tags: trunk
Changes

Modified pluginconf/bind.py from [f6f6f09ee5] to [eb3faffd0a].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28


29
30
31
32
33
34
35
# encoding: utf-8
# api: pluginconf
##type: loader
# title: plugin loader
# description: implements a trivial unified namespace importer
# version: 0.1
# state: alpha
# priority: optional
#
# Most basic plugin management/loader. It unifies meta data retrieval
# and instantiation. It still doesn't dictate a plugin API or config
# storage (using json in examples). And can be a simpler setup:
#
# Create an empty plugins/__init__.py to use as package and for
# plugin discovery.
#
# Designate it as such:
#
#      import pluginconf.bind  # (first import resets .plugin_base)
#      pluginconf.bind.base("plugins")
#
# Set up a default conf={} in your application, with some presets,
# or updating it from a stored config file:
#
#      conf = {
#          "first_run": 1,
#          "debug": 0,
#          "plugins": {},


#      }
#      conf.update(
#          json.load(open("app.json", "r"))
#      )
#
# Then update defaults from plugins:
#





|





|















|
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# encoding: utf-8
# api: pluginconf
##type: loader
# title: plugin loader
# description: implements a trivial unified namespace importer
# version: 0.2
# state: alpha
# priority: optional
#
# Most basic plugin management/loader. It unifies meta data retrieval
# and instantiation. It still doesn't dictate a plugin API or config
# storage (using json in examples), but some simple structuring:
#
# Create an empty plugins/__init__.py to use as package and for
# plugin discovery.
#
# Designate it as such:
#
#      import pluginconf.bind  # (first import resets .plugin_base)
#      pluginconf.bind.base("plugins")
#
# Set up a default conf={} in your application, with some presets,
# or updating it from a stored config file:
#
#      conf = {
#          "first_run": 1,
#          "debug": 0,
#          "plugins": {
#              "mainwindow": True,
#          },
#      }
#      conf.update(
#          json.load(open("app.json", "r"))
#      )
#
# Then update defaults from plugins:
#
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#
# With PySimpleGUI, `conf` could be a psg.UserSettings("app.json") for
# automatic settings+update storage, btw.
#

#-- bit briefer for API docs --
"""
Basic plugin loader implementation for flat namespaces. Ties together

pluginconf lookups and config management for plugin loading in apps.
It's rather basic, and subject to change. Does impose a config dict
format, but no storage still.

### Usage example

    # designate a plugins/*.py package as plugin_base
    import plugins
    import pluginconf.bind
    pluginconf.bind.base(plugins)

    # preset core app settings / load from json, add plugin options
    conf = {
        "plugins": {
        }
    }
    pluginconf.bind.defaults(conf)

    # load conf-enabled plugins, and register modules somehow
    for mod in pluginconf.bind.load_enabled(conf):
        mod.init()

### Find by type







|
>
|
|
|






|


|
<
<
<







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103



104
105
106
107
108
109
110
#
# With PySimpleGUI, `conf` could be a psg.UserSettings("app.json") for
# automatic settings+update storage, btw.
#

#-- bit briefer for API docs --
"""
Basic plugin loader implementation. Plugins are assumed to reside
in a flat namespace (main difference to module imports). This ties
together pluginconf lookups and config management for plugin loading
in apps. It's rather basic, and subject to change. Does impose a
config dict format, but no storage still.

### Usage example

    # designate a plugins/*.py package as plugin_base
    import plugins
    import pluginconf.bind
    pluginconf.bind.base(__package__)  # or "plugins" etc.

    # preset core app settings / load from json, add plugin options
    conf = {}



    pluginconf.bind.defaults(conf)

    # load conf-enabled plugins, and register modules somehow
    for mod in pluginconf.bind.load_enabled(conf):
        mod.init()

### Find by type
235
236
237
238
239
240
241


242
243
244
245
246
247
248
    Traverse installed plugins and expand config dict with presets 🧩 🧾

    | Parameters  | | |
    |-------------|-----------|-------------------------------------------|
    | conf        | dict 🔁   | Expands the conf dict with preset values from any plugins. |
    | **Returns** | None      | -                                         |
    """


    for name, pmd in pluginconf.all_plugin_meta().items():
        pluginconf.add_plugin_defaults(conf, conf["plugins"], pmd, name)


# pylint: disable=invalid-name
class isolated():
    """







>
>







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
    Traverse installed plugins and expand config dict with presets 🧩 🧾

    | Parameters  | | |
    |-------------|-----------|-------------------------------------------|
    | conf        | dict 🔁   | Expands the conf dict with preset values from any plugins. |
    | **Returns** | None      | -                                         |
    """
    if not "plugins" in conf:
        conf["plugins"] = dict()
    for name, pmd in pluginconf.all_plugin_meta().items():
        pluginconf.add_plugin_defaults(conf, conf["plugins"], pmd, name)


# pylint: disable=invalid-name
class isolated():
    """
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
    def defaults():
        """ *return* defaults for isolated plugin structure 🧩 🧾 """
        conf = {"plugins": {}}
        defaults(conf)
        return conf


def _enable_cache(state=True):
    """
    Reduce plugin_meta() lookup costs, suitable for repeat find() calls
    """
    if hasattr(pluginconf.plugin_meta, "__wrapped__"):
        if state:
            return
        pluginconf.plugin_meta = pluginconf.plugin_meta.__wrapped__







|







295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
    def defaults():
        """ *return* defaults for isolated plugin structure 🧩 🧾 """
        conf = {"plugins": {}}
        defaults(conf)
        return conf


def cache(state=True):
    """
    Reduce plugin_meta() lookup costs, suitable for repeat find() calls
    """
    if hasattr(pluginconf.plugin_meta, "__wrapped__"):
        if state:
            return
        pluginconf.plugin_meta = pluginconf.plugin_meta.__wrapped__