Differences From Artifact [f6f6f09ee5]:

To Artifact [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
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.1
# 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). And can be a simpler setup:
# 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": {},
#          "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
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.
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(plugins)
    pluginconf.bind.base(__package__)  # or "plugins" etc.

    # preset core app settings / load from json, add plugin options
    conf = {
    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
235
236
237
238
239
240
241


242
243
244
245
246
247
248
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
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 _enable_cache(state=True):
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__