Skip to content

Commit 0556d7e

Browse files
committed
remove __init__ from global context names; see #111
1 parent 9220570 commit 0556d7e

File tree

5 files changed

+46
-35
lines changed

5 files changed

+46
-35
lines changed

custom_components/pyscript/__init__.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ def glob_read_files(load_paths, apps_config):
309309
mod_name = rel_path[0:-3]
310310
if mod_name.endswith("/__init__"):
311311
rel_import_path = mod_name
312+
mod_name = mod_name[: -len("/__init__")]
312313
mod_name = mod_name.replace("/", ".")
313314
if path == "":
314315
global_ctx_name = f"file.{mod_name}"
@@ -322,14 +323,12 @@ def glob_read_files(load_paths, apps_config):
322323

323324
if global_ctx_name in ctx2source:
324325
# the globs result in apps/APP/__init__.py matching twice, so skip the 2nd time
326+
# also skip apps/APP.py if apps/APP/__init__.py is present
325327
continue
326328

327-
if fq_mod_name.endswith(".__init__"):
328-
fq_mod_name = fq_mod_name[: -len(".__init__")]
329-
330329
if check_config:
331330
app_name = fq_mod_name
332-
i = fq_mod_name.find(".")
331+
i = app_name.find(".")
333332
if i >= 0:
334333
app_name = app_name[0:i]
335334
if not isinstance(apps_config, dict) or app_name not in apps_config:
@@ -365,11 +364,12 @@ def glob_read_files(load_paths, apps_config):
365364
return ctx2source
366365

367366
load_paths = [
368-
# directory, glob, check_config, autoload
367+
# path, glob, check_config, autoload
369368
["", "*.py", False, True],
370-
["apps", "*.py", True, True],
371369
["apps", "*/__init__.py", True, True],
370+
["apps", "*.py", True, True],
372371
["apps", "*/**/*.py", False, False],
372+
["modules", "*/__init__.py", False, False],
373373
["modules", "*.py", False, False],
374374
["modules", "*/**/*.py", False, False],
375375
["scripts", "**/*.py", False, True],

custom_components/pyscript/global_ctx.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -140,27 +140,22 @@ def find_first_file(file_paths):
140140
if path.find("/") < 0 or idx < 0:
141141
raise ImportError("attempted relative import above parent package")
142142
ctx_name = ctx_name[0:idx]
143-
idx = ctx_name.rfind(".")
144-
if idx >= 0:
145-
ctx_name = f"{ctx_name[0:idx]}.{module_name}"
146-
file_paths.append([ctx_name, f"{path}/{module_path}.py", path])
143+
ctx_name += f".{module_name}"
144+
module_info = [ctx_name, f"{path}/{module_path}.py", path]
147145
path += f"/{module_path}"
148-
file_paths.append([f"{ctx_name}.__init__", f"{path}/__init__.py", path])
146+
file_paths.append([ctx_name, f"{path}/__init__.py", path])
147+
file_paths.append(module_info)
149148
module_name = ctx_name[ctx_name.find(".") + 1 :]
150149

151150
else:
152151
if self.rel_import_path is not None and self.rel_import_path.startswith("apps/"):
153152
ctx_name = f"apps.{module_name}"
153+
file_paths.append([ctx_name, f"apps/{module_path}/__init__.py", f"apps/{module_path}"])
154154
file_paths.append([ctx_name, f"apps/{module_path}.py", f"apps/{module_path}"])
155-
file_paths.append(
156-
[f"{ctx_name}.__init__", f"apps/{module_path}/__init__.py", f"apps/{module_path}"]
157-
)
158155

159156
ctx_name = f"modules.{module_name}"
157+
file_paths.append([ctx_name, f"modules/{module_path}/__init__.py", f"modules/{module_path}"])
160158
file_paths.append([ctx_name, f"modules/{module_path}.py", None])
161-
file_paths.append(
162-
[f"{ctx_name}.__init__", f"modules/{module_path}/__init__.py", f"modules/{module_path}"]
163-
)
164159

165160
#
166161
# now see if we have loaded it already

docs/reference.rst

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,17 @@ they have changed when the ``pyscript.reload`` service is called, which also rel
6868
are autoloaded. This is useful for organizing your scripts into subdirectories that are
6969
related in some way.
7070

71-
``<config>/pyscript/apps/<app_name>.py``
72-
all files in the ``apps`` subdirectory with a ``.py`` suffix are autoloaded, provided ``app_name``
73-
exists in the pyscript ``yaml`` configuration under ``apps`` (that allows each app to be disabled by
74-
simply removing its configuration and reloading).
75-
7671
``<config>/pyscript/apps/<app_name>/__init__.py``
7772
every ``__init__.py`` file in a subdirectory in the ``apps`` subdirectory is autoloaded,
7873
provided ``app_name`` exists in the pyscript ``yaml`` configuration under ``apps``.
79-
This form is most convenient for sharing pyscript code, since all the files for one
80-
application are stored in its own directory.
74+
This package form is most convenient for sharing pyscript code, since all the files for
75+
one application are stored in their own directory.
76+
77+
``<config>/pyscript/apps/<app_name>.py``
78+
all files in the ``apps`` subdirectory with a ``.py`` suffix are autoloaded, unless the
79+
package form above was loaded instead, and provided ``app_name`` exists in the pyscript
80+
``yaml`` configuration under ``apps`` (that allows each app to be disabled by simply
81+
removing its configuration and reloading).
8182

8283
Any file name that starts with ``#`` is not loaded, and similarly scripts anywhere below a directory
8384
name that starts with ``#``, are not loaded. That's a convenient way to disable a specific script or
@@ -95,8 +96,9 @@ created by a script file, or even another Jupyter session.
9596

9697
The optional ``<config>/pyscript/modules`` subdirectory can contain modules (files with a ``.py``
9798
extension) or packages (directories that contain at least a ``__init__.py`` file) that can be
98-
imported by any other pyscript files, applications or modules. They are not autoloaded. Any modules
99-
or packages in ``<config>/pyscript/modules`` that are modified will be unloaded when you call the
99+
imported by any other pyscript files, applications or modules. The module form is ignored if the
100+
package form is presemt. They are not autoloaded. Any modules or packages in
101+
``<config>/pyscript/modules`` that are modified will be unloaded when you call the
100102
``pyscript.reload`` service. Importing modules and packages from ``<config>/pyscript/modules`` are
101103
not restricted if ``allow_all_imports`` is ``False``. Typically common functions or features would
102104
be implemented in a module or package, and then imported and used by scripts in
@@ -1100,10 +1102,10 @@ lower case are actual fixed names):
11001102
======================================= ===========================
11011103
``pyscript/FILE.py`` ``file.FILE``
11021104
``pyscript/modules/MODULE.py`` ``modules.MODULE``
1103-
``pyscript/modules/MODULE/__init__.py`` ``modules.MODULE.__init__``
1105+
``pyscript/modules/MODULE/__init__.py`` ``modules.MODULE``
11041106
``pyscript/modules/MODULE/FILE.py`` ``modules.MODULE.FILE``
11051107
``pyscript/apps/APP.py`` ``apps.APP``
1106-
``pyscript/apps/APP/__init__.py`` ``apps.APP.__init__``
1108+
``pyscript/apps/APP/__init__.py`` ``apps.APP``
11071109
``pyscript/apps/APP/FILE.py`` ``apps.APP.FILE``
11081110
``pyscript/scripts/FILE.py`` ``scripts.FILE``
11091111
``pyscript/scripts/DIR1/FILE.py`` ``scripts.DIR1.FILE``

tests/test_apps_modules.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ async def state_changed(event):
200200
ret = await wait_until_done(notify_q)
201201
assert literal_eval(ret) == [99, "xyz2", "xyz2.other", 1 + 5, 3 * 6, 10 + 30, 50 - 30]
202202

203-
assert "modules/xyz2 global_ctx=modules.xyz2.__init__;" in caplog.text
203+
assert "modules/xyz2 global_ctx=modules.xyz2;" in caplog.text
204204
assert "func14 global_ctx=scripts.a.b.c.d.func14;" in caplog.text
205205
assert "ModuleNotFoundError: import of no_such_package not allowed" in caplog.text
206206
assert "SyntaxError: invalid syntax (bad_module.py, line 2)" in caplog.text

tests/test_reload.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ def shutdown(trigger_time=None):
6969
log.info(f"modules/xyz2/other global_ctx={pyscript.get_global_ctx()};")
7070
7171
xyz = 123
72+
""",
73+
#
74+
# these shouldn't load since the package takes precedence
75+
#
76+
f"{conf_dir}/modules/xyz2.py": """
77+
log.info(f"BOTCH shouldn't load {__name__}")
78+
""",
79+
f"{conf_dir}/apps/world2.py": """
80+
log.info(f"BOTCH shouldn't load {__name__}")
7281
""",
7382
}
7483

@@ -123,11 +132,11 @@ async def state_changed(event):
123132
assert hass.services.has_service("pyscript", "func2")
124133
assert hass.services.has_service("pyscript", "func3")
125134

126-
assert "modules/xyz2 global_ctx=modules.xyz2.__init__;" in caplog.text
135+
assert "modules/xyz2 global_ctx=modules.xyz2;" in caplog.text
127136
assert "modules/xyz2/other global_ctx=modules.xyz2.other;" in caplog.text
128137
assert "hello global_ctx=file.hello xyz=123 xyz2.xyz=123" in caplog.text
129138
assert "world2.other global_ctx=apps.world2.other" in caplog.text
130-
assert "world2 global_ctx=apps.world2.__init__ var1=100, other_abc=987" in caplog.text
139+
assert "world2 global_ctx=apps.world2 var1=100, other_abc=987" in caplog.text
131140

132141
#
133142
# add a new script file
@@ -196,7 +205,7 @@ def func20():
196205
#
197206
conf["apps"]["world2"]["var1"] = 200
198207
await hass.services.async_call("pyscript", "reload", {}, blocking=True)
199-
assert "world2 global_ctx=apps.world2.__init__ var1=200, other_abc=987" in caplog.text
208+
assert "world2 global_ctx=apps.world2 var1=200, other_abc=987" in caplog.text
200209
assert "world2.other global_ctx=apps.world2.other shutdown trigger_time=shutdown" in caplog.text
201210

202211
#
@@ -217,7 +226,7 @@ def shutdown(trigger_time=None):
217226
f"{conf_dir}/apps/world2/other.py"
218227
]
219228
await hass.services.async_call("pyscript", "reload", {}, blocking=True)
220-
assert "world2 global_ctx=apps.world2.__init__ var1=200, other_abc=654" in caplog.text
229+
assert "world2 global_ctx=apps.world2 var1=200, other_abc=654" in caplog.text
221230
assert "world2.other global_ctx=apps.world2.other shutdown trigger_time=shutdown" in caplog.text
222231

223232
#
@@ -226,10 +235,10 @@ def shutdown(trigger_time=None):
226235
#
227236
for i in range(3):
228237
assert caplog.text.count("world global_ctx=apps.world xyz=") == 2 + i
229-
assert caplog.text.count("world2 global_ctx=apps.world2.__init__ var1=") == 3 + i
238+
assert caplog.text.count("world2 global_ctx=apps.world2 var1=") == 3 + i
230239
assert caplog.text.count("hello global_ctx=file.hello xyz=") == 4 + i
231240
assert caplog.text.count("modules/xyz2/other global_ctx=modules.xyz2.other") == 2 + i
232-
assert caplog.text.count("modules/xyz2 global_ctx=modules.xyz2.__init__") == 2 + i
241+
assert caplog.text.count("modules/xyz2 global_ctx=modules.xyz2") == 2 + i
233242
assert (
234243
caplog.text.count("world2.other global_ctx=apps.world2.other shutdown trigger_time=shutdown")
235244
== 2
@@ -242,3 +251,8 @@ def shutdown(trigger_time=None):
242251
)
243252
if i < 2:
244253
await hass.services.async_call("pyscript", "reload", {"global_ctx": "*"}, blocking=True)
254+
255+
#
256+
# make sure files that shouldn't load were not loaded
257+
#
258+
assert "BOTCH shouldn't load" not in caplog.text

0 commit comments

Comments
 (0)