pygitpub 0.0.59__tar.gz → 0.0.61__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pygitpub-0.0.59 → pygitpub-0.0.61}/.gitignore +51 -15
- {pygitpub-0.0.59 → pygitpub-0.0.61}/PKG-INFO +8 -5
- {pygitpub-0.0.59 → pygitpub-0.0.61}/README.md +4 -2
- {pygitpub-0.0.59 → pygitpub-0.0.61}/pyproject.toml +27 -4
- {pygitpub-0.0.59 → pygitpub-0.0.61}/src/pygitpub/main.py +56 -11
- {pygitpub-0.0.59 → pygitpub-0.0.61}/src/pygitpub/static.py +1 -1
- pygitpub-0.0.61/src/pygitpub/utils/lua.py +68 -0
- pygitpub-0.0.59/src/pygitpub/utils/importlib.py +0 -16
- {pygitpub-0.0.59 → pygitpub-0.0.61}/LICENSE +0 -0
- {pygitpub-0.0.59 → pygitpub-0.0.61}/src/pygitpub/__init__.py +0 -0
- {pygitpub-0.0.59 → pygitpub-0.0.61}/src/pygitpub/configs.py +0 -0
- {pygitpub-0.0.59 → pygitpub-0.0.61}/src/pygitpub/utils/__init__.py +0 -0
- {pygitpub-0.0.59 → pygitpub-0.0.61}/src/pygitpub/utils/misc.py +0 -0
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# generated
|
|
2
|
-
/build/
|
|
3
2
|
/toolchain/
|
|
4
3
|
/dist/
|
|
5
|
-
/target/
|
|
6
4
|
/out/
|
|
7
5
|
/debug/
|
|
8
6
|
/download/
|
|
@@ -64,7 +62,7 @@ modules.order
|
|
|
64
62
|
|
|
65
63
|
# sphinx
|
|
66
64
|
/docs/_build/
|
|
67
|
-
/docs/.doctrees/
|
|
65
|
+
/docs/.doctrees/
|
|
68
66
|
|
|
69
67
|
# mdBook build output
|
|
70
68
|
/docs/book/
|
|
@@ -77,8 +75,6 @@ modules.order
|
|
|
77
75
|
# python
|
|
78
76
|
__pycache__/
|
|
79
77
|
*.py[oc]
|
|
80
|
-
*.pyc
|
|
81
|
-
*.pyo
|
|
82
78
|
/wheel/
|
|
83
79
|
/.venv/
|
|
84
80
|
.coverage
|
|
@@ -87,7 +83,10 @@ coverage.xml
|
|
|
87
83
|
*.egg-info/
|
|
88
84
|
|
|
89
85
|
# mine
|
|
90
|
-
|
|
86
|
+
# error files left by the bashy prompt plugins (.uv.sync.errors,
|
|
87
|
+
# .pydmt.build.errors, ...); unanchored because a sub-project's
|
|
88
|
+
# pyproject root can sit below the git root
|
|
89
|
+
.*.errors
|
|
91
90
|
/.pydmt/
|
|
92
91
|
*.stamp
|
|
93
92
|
*.stamp.*
|
|
@@ -147,10 +146,13 @@ build/
|
|
|
147
146
|
.ipynb_checkpoints/
|
|
148
147
|
|
|
149
148
|
# c#
|
|
149
|
+
# **/obj/ and **/bin/ match at any depth, which is what .NET output needs
|
|
150
|
+
# (src/<proj>/bin, src/<proj>/obj). The un-globbed [Oo]bj/ and [Bb]in/ that
|
|
151
|
+
# used to follow were redundant with these two and are gone.
|
|
150
152
|
**/obj/
|
|
151
153
|
**/bin/
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
# perl-meta keeps real Perl sources under perl/bin/Meta/, not build output.
|
|
155
|
+
!/perl/bin/
|
|
154
156
|
|
|
155
157
|
# flash/air
|
|
156
158
|
*.swf
|
|
@@ -175,7 +177,6 @@ bin-release/
|
|
|
175
177
|
.project
|
|
176
178
|
.project.xml
|
|
177
179
|
.idea/
|
|
178
|
-
/.idea/
|
|
179
180
|
build.properties
|
|
180
181
|
|
|
181
182
|
# spark
|
|
@@ -186,24 +187,26 @@ spark-warehouse/
|
|
|
186
187
|
/.terraform/
|
|
187
188
|
terraform.tfstate
|
|
188
189
|
terraform.tfstate.backup
|
|
189
|
-
/terraform.tfstate
|
|
190
|
-
/terraform.tfstate.backup
|
|
191
190
|
/terraform.lock.hcl
|
|
192
191
|
|
|
193
192
|
# scala
|
|
194
|
-
|
|
195
|
-
project/
|
|
193
|
+
# Anchored: sbt's build dir is at the repo root. Unanchored, this also
|
|
194
|
+
# swallowed source directories named project/ nested under src/.
|
|
195
|
+
/project/
|
|
196
196
|
|
|
197
197
|
# rust
|
|
198
198
|
**/*.rs.bk
|
|
199
199
|
**/mutants.out*/
|
|
200
200
|
*.pdb
|
|
201
|
-
debug
|
|
201
|
+
# Anchored: this is the root debug build dir. Unanchored (and without a
|
|
202
|
+
# trailing slash) it matched any file or directory named debug at any depth,
|
|
203
|
+
# including authored example content.
|
|
204
|
+
/debug/
|
|
202
205
|
/.rsconstruct_cache.json
|
|
203
206
|
|
|
204
207
|
# claude
|
|
205
208
|
/.claude/
|
|
206
|
-
claude/
|
|
209
|
+
/claude/
|
|
207
210
|
.claude/projects/
|
|
208
211
|
.claude/settings.local.json
|
|
209
212
|
|
|
@@ -242,3 +245,36 @@ creds.txt
|
|
|
242
245
|
|
|
243
246
|
# rsconstruct
|
|
244
247
|
/.rsconstruct/
|
|
248
|
+
|
|
249
|
+
# generated website pieces (built into the Pages artifact by CI)
|
|
250
|
+
/docs/output/
|
|
251
|
+
/docs/index.html
|
|
252
|
+
# sphinx html output: the 14 py* repos render docs/ from sphinx/ and publish
|
|
253
|
+
# it as the Pages artifact, so none of it is committed. Listed path by path
|
|
254
|
+
# rather than as /docs/ because the rs* repos keep hand-written mdBook
|
|
255
|
+
# sources there, and several others keep authored html.
|
|
256
|
+
/docs/_modules/
|
|
257
|
+
/docs/_sources/
|
|
258
|
+
/docs/_static/
|
|
259
|
+
/docs/.buildinfo
|
|
260
|
+
/docs/objects.inv
|
|
261
|
+
/docs/searchindex.js
|
|
262
|
+
/docs/.nojekyll
|
|
263
|
+
# sphinx's top-level html. Not a blanket /docs/*.html: js-jschess and the
|
|
264
|
+
# site-personal-* repos keep hand-authored html under docs/. The fixed pages
|
|
265
|
+
# (genindex, modules, search) and the authored-rst pages some repos render
|
|
266
|
+
# (architecture, notes, ...) are listed by name; the one-page-per-module
|
|
267
|
+
# output is /docs/py*.html, since every package here is named py*.
|
|
268
|
+
/docs/architecture.html
|
|
269
|
+
/docs/cli-reference.html
|
|
270
|
+
/docs/development.html
|
|
271
|
+
/docs/genindex.html
|
|
272
|
+
/docs/modules.html
|
|
273
|
+
/docs/notes.html
|
|
274
|
+
/docs/overview.html
|
|
275
|
+
/docs/py*.html
|
|
276
|
+
/docs/quota-guide.html
|
|
277
|
+
/docs/search.html
|
|
278
|
+
|
|
279
|
+
# per-machine tool resolution cache (absolute paths, not portable)
|
|
280
|
+
/.tools.versions
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pygitpub
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.61
|
|
4
4
|
Summary: Pygitpub will help you work with github
|
|
5
5
|
Project-URL: Homepage, https://github.com/veltzer/pygitpub
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/veltzer/pygitpub/issues
|
|
@@ -19,9 +19,10 @@ Classifier: Operating System :: OS Independent
|
|
|
19
19
|
Classifier: Programming Language :: Python
|
|
20
20
|
Classifier: Programming Language :: Python :: 3
|
|
21
21
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
23
|
Classifier: Topic :: Utilities
|
|
24
|
-
Requires-Python: >=3.
|
|
24
|
+
Requires-Python: >=3.14
|
|
25
|
+
Requires-Dist: lupa
|
|
25
26
|
Requires-Dist: pyapikey
|
|
26
27
|
Requires-Dist: pygithub
|
|
27
28
|
Requires-Dist: pylogconf
|
|
@@ -29,6 +30,9 @@ Requires-Dist: pytconf
|
|
|
29
30
|
Requires-Dist: pyyaml
|
|
30
31
|
Description-Content-Type: text/markdown
|
|
31
32
|
|
|
33
|
+
<!-- This file is generated. Do not edit it by hand: your changes will be
|
|
34
|
+
lost on the next build. Edit the template it is rendered from, or the
|
|
35
|
+
values that template reads, and build again. -->
|
|
32
36
|
# *pygitpub* project by Mark Veltzer
|
|
33
37
|
|
|
34
38
|
description: Pygitpub will help you work with github
|
|
@@ -37,7 +41,7 @@ project website: https://veltzer.github.io/pygitpub
|
|
|
37
41
|
|
|
38
42
|
author: Mark Veltzer
|
|
39
43
|
|
|
40
|
-
version: 0.0.
|
|
44
|
+
version: 0.0.61
|
|
41
45
|
|
|
42
46
|

|
|
43
47
|
|
|
@@ -66,7 +70,6 @@ version: 0.0.59
|
|
|
66
70
|
## contact me
|
|
67
71
|
|
|
68
72
|
[mailto](mailto:mark.veltzer@gmail.com)
|
|
69
|
-

|
|
70
73
|

|
|
71
74
|

|
|
72
75
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
<!-- This file is generated. Do not edit it by hand: your changes will be
|
|
2
|
+
lost on the next build. Edit the template it is rendered from, or the
|
|
3
|
+
values that template reads, and build again. -->
|
|
1
4
|
# *pygitpub* project by Mark Veltzer
|
|
2
5
|
|
|
3
6
|
description: Pygitpub will help you work with github
|
|
@@ -6,7 +9,7 @@ project website: https://veltzer.github.io/pygitpub
|
|
|
6
9
|
|
|
7
10
|
author: Mark Veltzer
|
|
8
11
|
|
|
9
|
-
version: 0.0.
|
|
12
|
+
version: 0.0.61
|
|
10
13
|
|
|
11
14
|

|
|
12
15
|
|
|
@@ -35,7 +38,6 @@ version: 0.0.59
|
|
|
35
38
|
## contact me
|
|
36
39
|
|
|
37
40
|
[mailto](mailto:mark.veltzer@gmail.com)
|
|
38
|
-

|
|
39
41
|

|
|
40
42
|

|
|
41
43
|
|
|
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pygitpub"
|
|
7
|
-
version = "0.0.
|
|
8
|
-
requires-python = ">=3.
|
|
7
|
+
version = "0.0.61"
|
|
8
|
+
requires-python = ">=3.14"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Mark Veltzer", email = "mark.veltzer@gmail.com" }
|
|
11
11
|
]
|
|
@@ -26,7 +26,7 @@ classifiers = [
|
|
|
26
26
|
"Programming Language :: Python",
|
|
27
27
|
"Programming Language :: Python :: 3",
|
|
28
28
|
"Programming Language :: Python :: 3 :: Only",
|
|
29
|
-
"Programming Language :: Python :: 3.
|
|
29
|
+
"Programming Language :: Python :: 3.14",
|
|
30
30
|
"Topic :: Utilities",
|
|
31
31
|
"License :: OSI Approved :: MIT License",
|
|
32
32
|
]
|
|
@@ -36,6 +36,16 @@ dependencies = [
|
|
|
36
36
|
"PyGithub",
|
|
37
37
|
"pyapikey",
|
|
38
38
|
"pyyaml",
|
|
39
|
+
"lupa",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[dependency-groups]
|
|
43
|
+
dev = [
|
|
44
|
+
"mypy",
|
|
45
|
+
"pylint",
|
|
46
|
+
"pytest",
|
|
47
|
+
"ruff",
|
|
48
|
+
"sphinx",
|
|
39
49
|
]
|
|
40
50
|
|
|
41
51
|
[project.urls]
|
|
@@ -74,10 +84,23 @@ exclude = [
|
|
|
74
84
|
]
|
|
75
85
|
|
|
76
86
|
[tool.mypy]
|
|
77
|
-
python_version = "3.
|
|
87
|
+
python_version = "3.14"
|
|
78
88
|
warn_return_any = true
|
|
79
89
|
warn_unused_configs = true
|
|
90
|
+
mypy_path = "src:python:scripts"
|
|
91
|
+
explicit_package_bases = true
|
|
92
|
+
namespace_packages = true
|
|
80
93
|
|
|
94
|
+
# Third-party libraries without type stubs; `foo.*` also matches `foo` itself.
|
|
95
|
+
[[tool.mypy.overrides]]
|
|
96
|
+
module = [
|
|
97
|
+
"github.*",
|
|
98
|
+
"lupa.*",
|
|
99
|
+
"pyapikey.*",
|
|
100
|
+
"pylogconf.*",
|
|
101
|
+
"pytconf.*",
|
|
102
|
+
]
|
|
103
|
+
ignore_missing_imports = true
|
|
81
104
|
[tool.hatch.envs.default]
|
|
82
105
|
installer = "uv"
|
|
83
106
|
|
|
@@ -16,12 +16,13 @@ from pytconf.registry import the_registry
|
|
|
16
16
|
|
|
17
17
|
import pygitpub.static
|
|
18
18
|
from pygitpub.configs import AFFILIATIONS, ConfigAlgo, ConfigGithub, ConfigOutput
|
|
19
|
-
from pygitpub.utils.
|
|
19
|
+
from pygitpub.utils.lua import config_path, load_lua_file
|
|
20
20
|
from pygitpub.utils.misc import delete, get_all_git_repos
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def get_base_dir() -> str:
|
|
24
|
-
|
|
24
|
+
base_dir: str = ConfigAlgo.base_dir
|
|
25
|
+
return os.path.expanduser(base_dir)
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
def get_repo_folder(repo) -> str:
|
|
@@ -84,25 +85,25 @@ def fix_metadata() -> None:
|
|
|
84
85
|
continue
|
|
85
86
|
os.chdir(folder)
|
|
86
87
|
# print(f"doing [{folder}]...")
|
|
87
|
-
file_path = "
|
|
88
|
+
file_path = config_path("project")
|
|
88
89
|
if not os.path.isfile(file_path):
|
|
89
90
|
os.chdir(orig_folder)
|
|
90
91
|
continue
|
|
91
|
-
|
|
92
|
-
if not
|
|
92
|
+
project = load_lua_file(file_path)
|
|
93
|
+
if "DESCRIPTION_SHORT" not in project:
|
|
93
94
|
os.chdir(orig_folder)
|
|
94
95
|
continue
|
|
95
|
-
description_short =
|
|
96
|
+
description_short = project["DESCRIPTION_SHORT"]
|
|
96
97
|
if description_short != repo.description:
|
|
97
98
|
print(f"in {folder}...")
|
|
98
99
|
print(f"description_short is [{description_short}]")
|
|
99
100
|
print(f"repo.description is [{repo.description}]")
|
|
100
101
|
repo.edit(description=description_short)
|
|
101
|
-
if not
|
|
102
|
+
if "KEYWORDS" not in project:
|
|
102
103
|
print(f"{folder} no keywords")
|
|
103
104
|
os.chdir(orig_folder)
|
|
104
105
|
continue
|
|
105
|
-
keywords =
|
|
106
|
+
keywords = project["KEYWORDS"]
|
|
106
107
|
if set(keywords) != set(repo.get_topics()):
|
|
107
108
|
print(f"in {folder}...")
|
|
108
109
|
print(f"keywords is [{keywords}]")
|
|
@@ -193,15 +194,17 @@ def repos_list() -> None:
|
|
|
193
194
|
|
|
194
195
|
|
|
195
196
|
@register_endpoint(
|
|
196
|
-
description="Cleanup old failing or un-needed runs
|
|
197
|
+
description="Cleanup old failing or un-needed runs, deployments, and releases in all repositories",
|
|
197
198
|
configs=[
|
|
198
199
|
ConfigGithub,
|
|
199
200
|
ConfigOutput,
|
|
200
201
|
ConfigAlgo,
|
|
201
202
|
],
|
|
202
203
|
)
|
|
203
|
-
def
|
|
204
|
+
def cleanup() -> None:
|
|
205
|
+
# pylint: disable=too-many-branches
|
|
204
206
|
for repo in yield_repos():
|
|
207
|
+
# 1. Cleanup workflow runs
|
|
205
208
|
for workflow in repo.get_workflows():
|
|
206
209
|
existing = 0
|
|
207
210
|
for run in workflow.get_runs():
|
|
@@ -215,7 +218,9 @@ def runs_cleanup() -> None:
|
|
|
215
218
|
if run.head_branch != "master":
|
|
216
219
|
delete_it = True
|
|
217
220
|
# if its not a paged build and it failed then delete it
|
|
218
|
-
if workflow.name != "pages-build-deployment" and run.conclusion
|
|
221
|
+
if workflow.name != "pages-build-deployment" and run.conclusion in (
|
|
222
|
+
"failure", "cancelled", "timed_out", "startup_failure", "action_required"
|
|
223
|
+
):
|
|
219
224
|
delete_it = True
|
|
220
225
|
if existing >= 4:
|
|
221
226
|
delete_it = True
|
|
@@ -225,6 +230,46 @@ def runs_cleanup() -> None:
|
|
|
225
230
|
else:
|
|
226
231
|
existing += 1
|
|
227
232
|
|
|
233
|
+
# 2. Cleanup deployments
|
|
234
|
+
existing_deployments = 0
|
|
235
|
+
for deployment in repo.get_deployments():
|
|
236
|
+
state = None
|
|
237
|
+
for status in deployment.get_statuses():
|
|
238
|
+
state = status.state
|
|
239
|
+
break
|
|
240
|
+
|
|
241
|
+
delete_it = False
|
|
242
|
+
if state in ("failure", "error") or existing_deployments >= 4:
|
|
243
|
+
delete_it = True
|
|
244
|
+
else:
|
|
245
|
+
existing_deployments += 1
|
|
246
|
+
|
|
247
|
+
if delete_it:
|
|
248
|
+
print(f"deleting deployment {repo.name} {deployment.id}")
|
|
249
|
+
try:
|
|
250
|
+
deployment.create_status("inactive")
|
|
251
|
+
except github.GithubException as e:
|
|
252
|
+
print(f"Failed to deactivate deployment: {e}")
|
|
253
|
+
try:
|
|
254
|
+
# pylint: disable=protected-access
|
|
255
|
+
status, _, _ = deployment._requester.requestJson("DELETE", deployment.url)
|
|
256
|
+
if status != 204:
|
|
257
|
+
print(f"Failed to delete deployment: HTTP {status}")
|
|
258
|
+
except github.GithubException as e:
|
|
259
|
+
print(f"Failed to delete deployment: {e}")
|
|
260
|
+
|
|
261
|
+
# 3. Cleanup releases
|
|
262
|
+
existing_releases = 0
|
|
263
|
+
for release in repo.get_releases():
|
|
264
|
+
if existing_releases >= 4:
|
|
265
|
+
print(f"deleting release {repo.name} {release.title}")
|
|
266
|
+
try:
|
|
267
|
+
release.delete_release()
|
|
268
|
+
except github.GithubException as e:
|
|
269
|
+
print(f"Failed to delete release: {e}")
|
|
270
|
+
else:
|
|
271
|
+
existing_releases += 1
|
|
272
|
+
|
|
228
273
|
|
|
229
274
|
@register_endpoint(
|
|
230
275
|
description="Show all runs in all workflows in all repos",
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Load "config/*.lua" data files.
|
|
3
|
+
|
|
4
|
+
The config files used to be python modules loaded via importlib; they are now
|
|
5
|
+
lua data files (config/project.lua and friends). A file is run in a fresh lua
|
|
6
|
+
runtime and the globals it declares are returned as a plain dict.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os.path
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
# lupa exposes LuaRuntime through a module level __getattr__ that points at the
|
|
13
|
+
# bundled lua version (lupa.lua54, lupa.lua55, ...), so it cannot be imported
|
|
14
|
+
# by name. Going through the package attribute works for any bundled version.
|
|
15
|
+
import lupa
|
|
16
|
+
|
|
17
|
+
CONFIG_FOLDER = "config"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def lua_to_python(value: Any) -> Any:
|
|
21
|
+
"""
|
|
22
|
+
Recursively convert a lua value into its python equivalent.
|
|
23
|
+
|
|
24
|
+
Lua has a single table type, so a table is a list if its keys are exactly
|
|
25
|
+
1..n and a dict otherwise. An empty table becomes an empty list, which
|
|
26
|
+
matches how the config files use them.
|
|
27
|
+
"""
|
|
28
|
+
if not hasattr(value, "values"):
|
|
29
|
+
return value
|
|
30
|
+
keys = list(value.keys())
|
|
31
|
+
if keys == list(range(1, len(keys) + 1)):
|
|
32
|
+
return [lua_to_python(x) for x in value.values()]
|
|
33
|
+
return {k: lua_to_python(value[k]) for k in keys}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def config_path(name: str) -> str:
|
|
37
|
+
""" return the path of a config file by its short name ("project") """
|
|
38
|
+
return os.path.join(CONFIG_FOLDER, f"{name}.lua")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def load_lua_file(path: str) -> dict[str, Any]:
|
|
42
|
+
"""
|
|
43
|
+
Run a lua file and return the globals it declared as a dict.
|
|
44
|
+
|
|
45
|
+
Raises FileNotFoundError if the file does not exist.
|
|
46
|
+
"""
|
|
47
|
+
if not os.path.isfile(path):
|
|
48
|
+
raise FileNotFoundError(path)
|
|
49
|
+
runtime = lupa.LuaRuntime()
|
|
50
|
+
with open(path, encoding="utf-8") as stream:
|
|
51
|
+
runtime.execute(stream.read())
|
|
52
|
+
globals_table = runtime.globals()
|
|
53
|
+
values = {}
|
|
54
|
+
for key in globals_table:
|
|
55
|
+
# skip the lua standard library, we only want what the file declared
|
|
56
|
+
if key in _LUA_BUILTINS:
|
|
57
|
+
continue
|
|
58
|
+
values[key] = lua_to_python(globals_table[key])
|
|
59
|
+
return values
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
_LUA_BUILTINS = frozenset({
|
|
63
|
+
"_G", "_VERSION", "assert", "collectgarbage", "coroutine", "debug", "dofile",
|
|
64
|
+
"error", "getmetatable", "io", "ipairs", "load", "loadfile", "math", "next",
|
|
65
|
+
"os", "package", "pairs", "pcall", "print", "python", "rawequal", "rawget",
|
|
66
|
+
"rawlen", "rawset", "require", "select", "setmetatable", "string", "table",
|
|
67
|
+
"tonumber", "tostring", "type", "utf8", "warn", "xpcall",
|
|
68
|
+
})
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
""" importlib.py """
|
|
2
|
-
|
|
3
|
-
import importlib.util
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def module_exists(module_name):
|
|
7
|
-
""" return if a module exists or not """
|
|
8
|
-
spec = importlib.util.find_spec(module_name)
|
|
9
|
-
return spec is not None
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def import_file(file_path):
|
|
13
|
-
spec = importlib.util.spec_from_file_location("foo", file_path)
|
|
14
|
-
mod = importlib.util.module_from_spec(spec)
|
|
15
|
-
spec.loader.exec_module(mod)
|
|
16
|
-
return mod
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|