diracx-testing 0.0.1a33__py3-none-any.whl → 0.0.1a35__py3-none-any.whl
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.
- diracx/testing/client_generation.py +156 -0
- diracx/testing/dummy_osdb.py +1 -1
- diracx/testing/mock_osdb.py +1 -1
- {diracx_testing-0.0.1a33.dist-info → diracx_testing-0.0.1a35.dist-info}/METADATA +1 -1
- diracx_testing-0.0.1a35.dist-info/RECORD +12 -0
- diracx_testing-0.0.1a33.dist-info/RECORD +0 -11
- {diracx_testing-0.0.1a33.dist-info → diracx_testing-0.0.1a35.dist-info}/WHEEL +0 -0
- {diracx_testing-0.0.1a33.dist-info → diracx_testing-0.0.1a35.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,156 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
__all__ = [
|
4
|
+
"regenerate_client",
|
5
|
+
"AUTOREST_VERSION",
|
6
|
+
]
|
7
|
+
|
8
|
+
import ast
|
9
|
+
import importlib.util
|
10
|
+
import subprocess
|
11
|
+
from pathlib import Path
|
12
|
+
|
13
|
+
import git
|
14
|
+
|
15
|
+
AUTOREST_VERSION = "6.13.7"
|
16
|
+
|
17
|
+
|
18
|
+
def extract_static_all(path):
|
19
|
+
tree = ast.parse(path.read_text(), filename=path)
|
20
|
+
|
21
|
+
name_to_module = {}
|
22
|
+
for node in tree.body:
|
23
|
+
if isinstance(node, ast.ImportFrom):
|
24
|
+
# Skip wildcard imports (like 'from ... import *')
|
25
|
+
for alias in node.names:
|
26
|
+
if alias.name == "*":
|
27
|
+
continue
|
28
|
+
# Use the alias if available, otherwise the original name.
|
29
|
+
local_name = alias.asname if alias.asname else alias.name
|
30
|
+
name_to_module[local_name] = node.module
|
31
|
+
|
32
|
+
# Look for the first top-level assignment to __all__
|
33
|
+
for node in tree.body:
|
34
|
+
if not isinstance(node, ast.Assign):
|
35
|
+
continue
|
36
|
+
for target in node.targets:
|
37
|
+
if not (isinstance(target, ast.Name) and target.id == "__all__"):
|
38
|
+
continue
|
39
|
+
return {
|
40
|
+
name: name_to_module.get(name) for name in ast.literal_eval(node.value)
|
41
|
+
}
|
42
|
+
raise NotImplementedError("__all__ not found")
|
43
|
+
|
44
|
+
|
45
|
+
def fixup_models_init(generated_dir, extension_name):
|
46
|
+
"""Workaround for https://github.com/python/mypy/issues/15300."""
|
47
|
+
models_init_path = generated_dir / "models" / "__init__.py"
|
48
|
+
# Enums cannot be extended, so we don't need to patch them
|
49
|
+
object_names = {
|
50
|
+
name
|
51
|
+
for name, module in extract_static_all(models_init_path).items()
|
52
|
+
if module != "_enums"
|
53
|
+
}
|
54
|
+
|
55
|
+
patch_module = "diracx.client._generated.models._patch"
|
56
|
+
spec = importlib.util.find_spec(patch_module)
|
57
|
+
if spec is None or spec.origin is None:
|
58
|
+
raise ImportError(f"Cannot locate {patch_module} package")
|
59
|
+
missing = set(extract_static_all(Path(spec.origin))) - set(object_names)
|
60
|
+
missing_formatted = "\n".join(f' "{name}",' for name in missing)
|
61
|
+
|
62
|
+
with models_init_path.open("a") as fh:
|
63
|
+
fh.write(
|
64
|
+
"if TYPE_CHECKING:\n"
|
65
|
+
" __all__.extend(\n"
|
66
|
+
" [\n"
|
67
|
+
f"{missing_formatted}"
|
68
|
+
" ]\n"
|
69
|
+
" )\n"
|
70
|
+
)
|
71
|
+
|
72
|
+
|
73
|
+
def regenerate_client(openapi_spec: Path, client_module: str):
|
74
|
+
"""Regenerate the AutoREST client and run pre-commit checks on it.
|
75
|
+
|
76
|
+
This test is skipped by default, and can be enabled by passing
|
77
|
+
--regenerate-client to pytest. It is intended to be run manually
|
78
|
+
when the API changes.
|
79
|
+
|
80
|
+
The reason this is a test is that it is the only way to get access to the
|
81
|
+
test_client fixture, which is required to get the OpenAPI spec.
|
82
|
+
|
83
|
+
WARNING: This test will modify the source code of the client!
|
84
|
+
"""
|
85
|
+
spec = importlib.util.find_spec(client_module)
|
86
|
+
if spec is None:
|
87
|
+
raise ImportError("Cannot locate client_module package")
|
88
|
+
if spec.origin is None:
|
89
|
+
raise ImportError(
|
90
|
+
"Cannot locate client_module package, did you forget the __init__.py?"
|
91
|
+
)
|
92
|
+
client_root = Path(spec.origin).parent
|
93
|
+
|
94
|
+
assert client_root.is_dir()
|
95
|
+
assert client_root.name == "client"
|
96
|
+
assert (client_root / "_generated").is_dir()
|
97
|
+
extension_name = client_root.parent.name
|
98
|
+
|
99
|
+
repo_root = client_root.parents[3]
|
100
|
+
if extension_name == "gubbins":
|
101
|
+
# Gubbins is special because it has a different structure due to being
|
102
|
+
# in a subdirectory of diracx
|
103
|
+
repo_root = repo_root.parents[1]
|
104
|
+
assert (repo_root / ".git").is_dir()
|
105
|
+
repo = git.Repo(repo_root)
|
106
|
+
generated_dir = client_root / "_generated"
|
107
|
+
if repo.is_dirty(path=generated_dir):
|
108
|
+
raise AssertionError(
|
109
|
+
"Client is currently in a modified state, skipping regeneration"
|
110
|
+
)
|
111
|
+
|
112
|
+
cmd = [
|
113
|
+
"autorest",
|
114
|
+
"--python",
|
115
|
+
f"--input-file={openapi_spec}",
|
116
|
+
"--models-mode=msrest",
|
117
|
+
"--namespace=_generated",
|
118
|
+
f"--output-folder={client_root}",
|
119
|
+
]
|
120
|
+
|
121
|
+
# This is required to be able to work offline
|
122
|
+
# TODO: if offline, find the version already installed
|
123
|
+
# and use it
|
124
|
+
# cmd += [f"--use=@autorest/python@{AUTOREST_VERSION}"]
|
125
|
+
|
126
|
+
# ruff: disable=S603
|
127
|
+
subprocess.run(cmd, check=True)
|
128
|
+
|
129
|
+
if extension_name != "diracx":
|
130
|
+
# For now we don't support extending the models in extensions. To make
|
131
|
+
# this clear manually remove the automatically generated _patch.py file
|
132
|
+
# and fixup the __init__.py file to use the diracx one.
|
133
|
+
(generated_dir / "models" / "_patch.py").unlink()
|
134
|
+
models_init_path = generated_dir / "models" / "__init__.py"
|
135
|
+
models_init = models_init_path.read_text()
|
136
|
+
assert models_init.count("from ._patch import") == 4
|
137
|
+
models_init = models_init.replace(
|
138
|
+
"from ._patch import",
|
139
|
+
"from diracx.client._generated.models._patch import",
|
140
|
+
)
|
141
|
+
models_init_path.write_text(models_init)
|
142
|
+
|
143
|
+
fixup_models_init(generated_dir, extension_name)
|
144
|
+
|
145
|
+
cmd = ["pre-commit", "run", "--all-files"]
|
146
|
+
print("Running pre-commit...")
|
147
|
+
subprocess.run(cmd, check=False, cwd=repo_root)
|
148
|
+
print("Re-running pre-commit...")
|
149
|
+
proc = subprocess.run(cmd, check=False, cwd=repo_root)
|
150
|
+
if proc.returncode == 0 and not repo.is_dirty(path=generated_dir):
|
151
|
+
return
|
152
|
+
# Show the diff to aid debugging
|
153
|
+
print(repo.git.diff(generated_dir))
|
154
|
+
if proc.returncode != 0:
|
155
|
+
raise AssertionError("Pre-commit failed")
|
156
|
+
raise AssertionError("Client was regenerated with changes")
|
diracx/testing/dummy_osdb.py
CHANGED
@@ -26,5 +26,5 @@ class DummyOSDB(BaseOSDB):
|
|
26
26
|
self.index_prefix = f"dummy_{secrets.token_hex(8)}"
|
27
27
|
super().__init__(*args, **kwargs)
|
28
28
|
|
29
|
-
def index_name(self, doc_id: int) -> str:
|
29
|
+
def index_name(self, vo: str, doc_id: int) -> str:
|
30
30
|
return f"{self.index_prefix}-{doc_id // 1e6:.0f}m"
|
diracx/testing/mock_osdb.py
CHANGED
@@ -86,7 +86,7 @@ class MockOSDBMixin:
|
|
86
86
|
async with self._sql_db.engine.begin() as conn:
|
87
87
|
await conn.run_sync(self._sql_db.metadata.create_all)
|
88
88
|
|
89
|
-
async def upsert(self, doc_id, document) -> None:
|
89
|
+
async def upsert(self, vo, doc_id, document) -> None:
|
90
90
|
async with self._sql_db:
|
91
91
|
values = {}
|
92
92
|
for key, value in document.items():
|
@@ -0,0 +1,12 @@
|
|
1
|
+
diracx/testing/__init__.py,sha256=nGbnGP8m53N9rqHR-hyqDa5vetcsmnQp806HadV6_dE,984
|
2
|
+
diracx/testing/client_generation.py,sha256=vegOUVQPcB7NTUFDr0HbasH5eByKQvLh_xYqKBYajzk,5539
|
3
|
+
diracx/testing/dummy_osdb.py,sha256=ptLrrreOHJBKMV7S1pR_k83jl-aLKvw7bFZufB6570Y,916
|
4
|
+
diracx/testing/entrypoints.py,sha256=ql7byyUOnUBdDoiN5xznlUTQSbD1YCNy4UF5t9MBhgc,2330
|
5
|
+
diracx/testing/mock_osdb.py,sha256=2pl9yKV1-e5kzf6meBZnhoc1i0ySAJ8IdnP3r1bOwcI,6033
|
6
|
+
diracx/testing/osdb.py,sha256=m6mUBLnGOoQLTCIBie9P2GhmLMybrgzIrlIYfhF1_Ss,3230
|
7
|
+
diracx/testing/routers.py,sha256=UW-TnikMQgcNxF5sUZD5DWoucGiCpP6s8mYmuahDiSc,979
|
8
|
+
diracx/testing/utils.py,sha256=T3tTzEOhmibcIu6TPwvoaZ6lFgHlU0t9FDHSetKP5EI,24341
|
9
|
+
diracx_testing-0.0.1a35.dist-info/METADATA,sha256=AG67paeB_J7uwKUOlbf8E0KOOM0G3Ssgel2mMp5Ohmk,634
|
10
|
+
diracx_testing-0.0.1a35.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
11
|
+
diracx_testing-0.0.1a35.dist-info/top_level.txt,sha256=vJx10tdRlBX3rF2Psgk5jlwVGZNcL3m_7iQWwgPXt-U,7
|
12
|
+
diracx_testing-0.0.1a35.dist-info/RECORD,,
|
@@ -1,11 +0,0 @@
|
|
1
|
-
diracx/testing/__init__.py,sha256=nGbnGP8m53N9rqHR-hyqDa5vetcsmnQp806HadV6_dE,984
|
2
|
-
diracx/testing/dummy_osdb.py,sha256=bNk3LF8KgMuQx3RVFNYuw4hMmpG2A80sZ58rEZqHo7M,907
|
3
|
-
diracx/testing/entrypoints.py,sha256=ql7byyUOnUBdDoiN5xznlUTQSbD1YCNy4UF5t9MBhgc,2330
|
4
|
-
diracx/testing/mock_osdb.py,sha256=hHuvmQZ3212SaSGX11dQv4ki3ZWsmqJZFYwdn6kg2MA,6029
|
5
|
-
diracx/testing/osdb.py,sha256=m6mUBLnGOoQLTCIBie9P2GhmLMybrgzIrlIYfhF1_Ss,3230
|
6
|
-
diracx/testing/routers.py,sha256=UW-TnikMQgcNxF5sUZD5DWoucGiCpP6s8mYmuahDiSc,979
|
7
|
-
diracx/testing/utils.py,sha256=T3tTzEOhmibcIu6TPwvoaZ6lFgHlU0t9FDHSetKP5EI,24341
|
8
|
-
diracx_testing-0.0.1a33.dist-info/METADATA,sha256=KY5UVLn9WSrGR0sNw1aX7LpviZncixfvmn4dN2DVmv4,634
|
9
|
-
diracx_testing-0.0.1a33.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
10
|
-
diracx_testing-0.0.1a33.dist-info/top_level.txt,sha256=vJx10tdRlBX3rF2Psgk5jlwVGZNcL3m_7iQWwgPXt-U,7
|
11
|
-
diracx_testing-0.0.1a33.dist-info/RECORD,,
|
File without changes
|
File without changes
|