Skip to content

Commit c3cf76a

Browse files
committed
Change to not use FlatDict for metadata
1 parent 4fcee01 commit c3cf76a

File tree

2 files changed

+53
-56
lines changed

2 files changed

+53
-56
lines changed

simvue/metadata.py

Lines changed: 36 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import toml
1313
import logging
1414
import pathlib
15-
import flatdict
1615

1716
from simvue.utilities import simvue_timestamp
1817

@@ -84,34 +83,32 @@ def _python_env(repository: pathlib.Path) -> dict[str, typing.Any]:
8483
if (pyproject_file := pathlib.Path(repository).joinpath("pyproject.toml")).exists():
8584
content = toml.load(pyproject_file)
8685
if (poetry_content := content.get("tool", {}).get("poetry", {})).get("name"):
87-
python_meta |= {
88-
"python.project.name": poetry_content["name"],
89-
"python.project.version": poetry_content["version"],
86+
python_meta["project"] = {
87+
"name": poetry_content["name"],
88+
"version": poetry_content["version"],
9089
}
9190
elif other_content := content.get("project"):
92-
python_meta |= {
93-
"python.project.name": other_content["name"],
94-
"python.project.version": other_content["version"],
91+
python_meta["project"] = {
92+
"name": other_content["name"],
93+
"version": other_content["version"],
9594
}
9695

9796
if (poetry_lock_file := pathlib.Path(repository).joinpath("poetry.lock")).exists():
9897
content = toml.load(poetry_lock_file).get("package", {})
99-
python_meta |= {
100-
f"python.environment.{package['name']}": package["version"]
101-
for package in content
98+
python_meta["environment"] = {
99+
package["name"]: package["version"] for package in content
102100
}
103101
elif (uv_lock_file := pathlib.Path(repository).joinpath("uv.lock")).exists():
104102
content = toml.load(uv_lock_file).get("package", {})
105-
python_meta |= {
106-
f"python.environment.{package['name']}": package["version"]
107-
for package in content
103+
python_meta["environment"] = {
104+
package["name"]: package["version"] for package in content
108105
}
109106
else:
110107
with contextlib.suppress((KeyError, ImportError)):
111108
from pip._internal.operations.freeze import freeze
112109

113-
python_meta |= {
114-
f"python.environment.{entry[0]}": entry[-1]
110+
python_meta["environment"] = {
111+
entry[0]: entry[-1]
115112
for line in freeze(local_only=True)
116113
if (entry := line.split("=="))
117114
}
@@ -126,35 +123,33 @@ def _rust_env(repository: pathlib.Path) -> dict[str, typing.Any]:
126123
if (cargo_file := pathlib.Path(repository).joinpath("Cargo.toml")).exists():
127124
content = toml.load(cargo_file).get("package", {})
128125
if version := content.get("version"):
129-
rust_meta |= {"rust.project.version": version}
126+
rust_meta.setdefault("project", {})["version"] = version
130127

131128
if name := content.get("name"):
132-
rust_meta |= {"rust.project.name": name}
129+
rust_meta.setdefault("project", {})["name"] = name
133130

134131
if not (cargo_lock := pathlib.Path(repository).joinpath("Cargo.lock")).exists():
135-
return {}
132+
return rust_meta
136133

137134
cargo_dat = toml.load(cargo_lock)
138-
139-
return rust_meta | {
140-
f"rust.environment.{dependency['name']}": dependency["version"]
135+
rust_meta["environment"] = {
136+
dependency["name"]: dependency["version"]
141137
for dependency in cargo_dat.get("package")
142138
}
143139

140+
return rust_meta
141+
144142

145143
def _julia_env(repository: pathlib.Path) -> dict[str, typing.Any]:
146144
"""Retrieve a dictionary of Julia dependencies if a project file is available"""
147145
julia_meta: dict[str, str] = {}
148146
if (project_file := pathlib.Path(repository).joinpath("Project.toml")).exists():
149147
content = toml.load(project_file)
150-
julia_meta |= {
151-
f"julia.project.{key}": value
152-
for key, value in content.items()
153-
if not isinstance(value, dict)
148+
julia_meta["project"] = {
149+
key: value for key, value in content.items() if not isinstance(value, dict)
154150
}
155-
julia_meta |= {
156-
f"julia.environment.{key}": value
157-
for key, value in content.get("compat", {}).items()
151+
julia_meta["environment"] = {
152+
key: value for key, value in content.get("compat", {}).items()
158153
}
159154
return julia_meta
160155

@@ -171,13 +166,11 @@ def _node_js_env(repository: pathlib.Path) -> dict[str, typing.Any]:
171166
)
172167
return {}
173168

174-
js_meta |= {
175-
f"javascript.project.{key}": value
176-
for key, value in content.items()
177-
if key in ("name", "version")
169+
js_meta["project"] = {
170+
key: value for key, value in content.items() if key in ("name", "version")
178171
}
179-
js_meta |= {
180-
f"javascript.environment.{key.replace('@', '')}": value["version"]
172+
js_meta["environment"] = {
173+
key.replace("@", ""): value["version"]
181174
for key, value in content.get(
182175
"packages" if lfv in (2, 3) else "dependencies", {}
183176
).items()
@@ -188,16 +181,13 @@ def _node_js_env(repository: pathlib.Path) -> dict[str, typing.Any]:
188181

189182
def environment(repository: pathlib.Path = pathlib.Path.cwd()) -> dict[str, typing.Any]:
190183
"""Retrieve environment metadata"""
191-
_environment_meta = flatdict.FlatDict(
192-
_python_env(repository), delimiter="."
193-
).as_dict()
194-
_environment_meta |= flatdict.FlatDict(
195-
_rust_env(repository), delimiter="."
196-
).as_dict()
197-
_environment_meta |= flatdict.FlatDict(
198-
_julia_env(repository), delimiter="."
199-
).as_dict()
200-
_environment_meta |= flatdict.FlatDict(
201-
_node_js_env(repository), delimiter="."
202-
).as_dict()
184+
_environment_meta = {}
185+
if _python_meta := _python_env(repository):
186+
_environment_meta["python"] = _python_meta
187+
if _rust_meta := _rust_env(repository):
188+
_environment_meta["rust"] = _rust_meta
189+
if _julia_meta := _julia_env(repository):
190+
_environment_meta["julia"] = _julia_meta
191+
if _js_meta := _node_js_env(repository):
192+
_environment_meta["javascript"] = _js_meta
203193
return _environment_meta

tests/unit/test_metadata.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
@pytest.mark.local
99
def test_cargo_env() -> None:
1010
metadata = sv_meta._rust_env(pathlib.Path(__file__).parents[1].joinpath("example_data"))
11-
assert metadata["rust.environment.serde"] == "1.0.123"
12-
assert metadata["rust.project.name"] == "example_project"
11+
assert metadata["environment"]["serde"] == "1.0.123"
12+
assert metadata["project"]["name"] == "example_project"
1313

1414
@pytest.mark.metadata
1515
@pytest.mark.local
@@ -19,29 +19,36 @@ def test_cargo_env() -> None:
1919
def test_python_env(backend: str | None) -> None:
2020
if backend == "poetry":
2121
metadata = sv_meta._python_env(pathlib.Path(__file__).parents[1].joinpath("example_data", "python_poetry"))
22-
assert metadata["python.project.name"] == "example-repo"
22+
assert metadata["project"]["name"] == "example-repo"
2323
elif backend == "uv":
2424
metadata = sv_meta._python_env(pathlib.Path(__file__).parents[1].joinpath("example_data", "python_uv"))
25-
assert metadata["python.project.name"] == "example-repo"
25+
assert metadata["project"]["name"] == "example-repo"
2626
else:
2727
metadata = sv_meta._python_env(pathlib.Path(__file__).parents[1].joinpath("example_data"))
2828

29-
assert re.findall(r"\d+\.\d+\.\d+", metadata["python.environment.numpy"])
29+
assert re.findall(r"\d+\.\d+\.\d+", metadata["environment"]["numpy"])
3030

3131

3232
@pytest.mark.metadata
3333
@pytest.mark.local
3434
def test_julia_env() -> None:
3535
metadata = sv_meta._julia_env(pathlib.Path(__file__).parents[1].joinpath("example_data"))
36-
assert metadata["julia.project.name"] == "Julia Demo Project"
37-
assert re.findall(r"\d+\.\d+\.\d+", metadata["julia.environment.AbstractDifferentiation"])
36+
assert metadata["project"]["name"] == "Julia Demo Project"
37+
assert re.findall(r"\d+\.\d+\.\d+", metadata["environment"]["AbstractDifferentiation"])
3838

3939

4040
@pytest.mark.metadata
4141
@pytest.mark.local
4242
def test_js_env() -> None:
4343
metadata = sv_meta._node_js_env(pathlib.Path(__file__).parents[1].joinpath("example_data"))
44-
assert metadata["javascript.project.name"] == "my-awesome-project"
45-
assert re.findall(r"\d+\.\d+\.\d+", metadata["javascript.environment.node_modules/dotenv"])
46-
44+
assert metadata["project"]["name"] == "my-awesome-project"
45+
assert re.findall(r"\d+\.\d+\.\d+", metadata["environment"]["node_modules/dotenv"])
4746

47+
@pytest.mark.metadata
48+
@pytest.mark.local
49+
def test_environment() -> None:
50+
metadata = sv_meta.environment(pathlib.Path(__file__).parents[1].joinpath("example_data"))
51+
assert metadata["python"]["project"]["name"] == "example-repo"
52+
assert metadata["rust"]["project"]["name"] == "example_project"
53+
assert metadata["julia"]["project"]["name"] == "Julia Demo Project"
54+
assert metadata["javascript"]["project"]["name"] == "my-awesome-project"

0 commit comments

Comments
 (0)