nmk-python 1.9.1__py3-none-any.whl → 1.10.1__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.
File without changes
@@ -0,0 +1,118 @@
1
+ from pathlib import Path
2
+
3
+ from buildenv.extension import BuildEnvRenderer
4
+ from jinja2 import Environment, PackageLoader
5
+ from nmk_base._buildenv.template import NmkBaseProjectTemplate, NmkConfigType, NmkReference
6
+
7
+ _ENV = Environment(loader=PackageLoader("nmk_python"))
8
+ _SRC_PATH = Path("src")
9
+
10
+
11
+ class NmkPythonProjectTemplate(NmkBaseProjectTemplate):
12
+ """
13
+ Template for **nmk-python** plugin project
14
+ """
15
+
16
+ @property
17
+ def weight(self) -> int:
18
+ # Top level plugin weight
19
+ return 300
20
+
21
+ @property
22
+ def references(self) -> list[NmkReference]:
23
+ return super().references + [NmkReference("nmk-python!plugin.yml", ["nmk-base!plugin.yml"])]
24
+
25
+ @property
26
+ def description(self) -> str:
27
+ return "python nmk project"
28
+
29
+ @property
30
+ def preferred_backend(self):
31
+ return "uv"
32
+
33
+ @property
34
+ def generated_files(self) -> set[Path]:
35
+ return super().generated_files | set(
36
+ [
37
+ Path("pyproject.toml"),
38
+ _SRC_PATH / self.python_module_name / "__init__.py",
39
+ _SRC_PATH / self.python_module_name / "sample.py",
40
+ _SRC_PATH / "tests" / "__init__.py",
41
+ _SRC_PATH / "tests" / "test_sample.py",
42
+ ]
43
+ )
44
+
45
+ @property
46
+ def post_generation_tasks(self) -> list[str]:
47
+ return super().post_generation_tasks + ["py.project"]
48
+
49
+ @property
50
+ def ignored_tasks(self) -> list[str]:
51
+ # Only ignore requirements.txt for uv backend
52
+ return super().ignored_tasks + (["py.req"] if self.info.backend_name == "uv" else [])
53
+
54
+ @property
55
+ def python_module_name(self) -> str:
56
+ # Deduce the python module name from the project name
57
+ return self.project_name.replace("-", "_")
58
+
59
+ @property
60
+ def comments(self) -> dict[str, str]:
61
+ return super().comments | {
62
+ "config.venvPkgDeps": "\nDevelopment dependencies (tools)",
63
+ "config.venvArchiveDeps": "\nDevelopment dependencies (tools, from local files)",
64
+ "config.pythonPackageRequirements": "\nPython package dependencies",
65
+ "config.pythonProjectFileItems": "\nExtra project settings",
66
+ }
67
+
68
+ def handle_dependencies(self, packages: list[str]) -> dict[str, NmkConfigType]:
69
+ # Iterate on packages
70
+ config_items: dict[str, NmkConfigType] = {}
71
+ simple_refs: list[str] = []
72
+ file_refs: list[str] = []
73
+ dep_refs: list[str] = []
74
+ for package in packages:
75
+ # Check for dependency groups (no group means it's a regular dependency, otherwise it's a dev dependency)
76
+ if ":" not in package:
77
+ dep_refs.append(package)
78
+ # Dev dependencies
79
+ else:
80
+ package = package.split(":")[-1] # Ignore dependency groups, if any (e.g. `dev:package` -> `package`)
81
+ if "." in package:
82
+ package_path = Path(package)
83
+ if package_path.is_absolute() and package_path.is_file():
84
+ file_refs.append(package)
85
+ elif (Path.cwd() / package).is_file():
86
+ file_refs.append(f"${{PROJECTDIR}}/{package}")
87
+ else:
88
+ simple_refs.append(package)
89
+ else:
90
+ simple_refs.append(package)
91
+
92
+ # Build settings
93
+ if dep_refs:
94
+ config_items["pythonPackageRequirements"] = dep_refs
95
+ if simple_refs:
96
+ config_items["venvPkgDeps"] = simple_refs
97
+ if file_refs:
98
+ config_items["venvArchiveDeps"] = file_refs
99
+
100
+ return config_items
101
+
102
+ def generate_extra_files(self, renderer: BuildEnvRenderer):
103
+ # Generate source code templates
104
+ keywords = {"python_module": self.python_module_name}
105
+ renderer.render(_ENV, "src/__init__.py.jinja", sub_path=_SRC_PATH / self.python_module_name, keywords=keywords)
106
+ renderer.render(_ENV, "src/__init__.py.jinja", sub_path=_SRC_PATH / "tests", keywords=keywords)
107
+ renderer.render(_ENV, "src/sample.py.jinja", sub_path=_SRC_PATH / self.python_module_name, keywords=keywords)
108
+ renderer.render(_ENV, "src/test_sample.py.jinja", sub_path=_SRC_PATH / "tests", keywords=keywords)
109
+
110
+ @property
111
+ def config_items(self) -> dict[str, NmkConfigType]:
112
+ items = dict(super().config_items)
113
+ items.update(
114
+ {
115
+ "pythonProjectFileItems": {"project": {"description": "Insert here a oneline description of your project"}},
116
+ }
117
+ )
118
+ return items
@@ -52,5 +52,5 @@ class UvBuildBackend(PythonBuildBackend):
52
52
  return build_dir / wheel_sub_dir / built_wheel_name
53
53
 
54
54
  def uninstall_wheels(self, wheel_names: list[str]):
55
- # Same as setup
56
- self._env_backend.upgrade(full=False, only_deps=True)
55
+ # Same as setup, just don't print updates (will be done by uninstall builder)
56
+ self._env_backend.upgrade(full=False, only_deps=True, print_updates=False)
nmk_python/build.py CHANGED
@@ -141,7 +141,7 @@ class Installer(NmkTaskBuilder):
141
141
  eb = cast(EnvBackend, self.model.env_backend) # type: ignore
142
142
  old_packages = eb.installed_packages
143
143
  BuildBackendFactory.create(self.model).install_wheel(wheel_path=Path(wheel))
144
- eb.print_updates(old_packages)
144
+ eb.print_updates(old_packages, ignored_packages=set([name]))
145
145
 
146
146
  # Remove stamp file
147
147
  Path(to_remove).unlink(missing_ok=True)
@@ -173,7 +173,7 @@ class Uninstaller(NmkTaskBuilder):
173
173
 
174
174
  # Delegate to build backend
175
175
  BuildBackendFactory.create(self.model).uninstall_wheels(wheel_names=sorted(list(wheel_names)))
176
- eb.print_updates(old_packages)
176
+ eb.print_updates(old_packages, ignored_packages=set([_python_package(self.model)]))
177
177
 
178
178
 
179
179
  class EditableBuilder(NmkTaskBuilder):
@@ -189,12 +189,13 @@ class EditableBuilder(NmkTaskBuilder):
189
189
  """
190
190
 
191
191
  # Check if project can be installed in editable mode
192
- if _can_install(_python_package(self.model), self.logger):
192
+ package_name = _python_package(self.model)
193
+ if _can_install(package_name, self.logger):
193
194
  # Delegate to build backend
194
195
  eb = cast(EnvBackend, self.model.env_backend) # type: ignore
195
196
  old_packages = eb.installed_packages
196
197
  BuildBackendFactory.create(self.model).install_editable()
197
- eb.print_updates(old_packages)
198
+ eb.print_updates(old_packages, ignored_packages=set([package_name]))
198
199
 
199
200
  # Touch stamp file
200
201
  self.main_output.touch()
@@ -311,3 +312,19 @@ class DepsMetadataBuilder(NmkTaskBuilder):
311
312
  indent=4,
312
313
  )
313
314
  )
315
+
316
+
317
+ class PythonIgnoredLockfileResolver(NmkListConfigResolver):
318
+ """
319
+ Python ignored lockfile resolver
320
+ """
321
+
322
+ def get_value(self, name: str) -> list[str]: # pyright: ignore[reportIncompatibleMethodOverride]
323
+ """
324
+ Return the list of lockfiles to be ignored, depending on the env backend and if the project is locked or not
325
+ """
326
+
327
+ # Ignore uv.lock file if using uv env backend and project is not locked
328
+ if not self.model.env_backend.is_locked and self.model.env_backend.name == "uv":
329
+ return ["uv.lock"] # pragma: no cover
330
+ return []
nmk_python/build.yml CHANGED
@@ -59,12 +59,17 @@ config:
59
59
  # Python editable install stamp
60
60
  pythonEditableStamp: ${outputDir}/.pyeditable
61
61
 
62
+ # Python ignored lockfile, depending on the env backend and if the project is locked or not
63
+ pythonIgnoredLockfile:
64
+ __resolver__: nmk_python.build.PythonIgnoredLockfileResolver
65
+
62
66
  # Python files to be ignored
63
67
  gitIgnoredFiles:
64
68
  - .eggs/
65
69
  - "*.egg-info/"
66
70
  - "*.pyc"
67
71
  - __pycache__
72
+ - ${pythonIgnoredLockfile}
68
73
 
69
74
  # Additional github publish step: publish on pypi.org
70
75
  githubPublishSteps:
@@ -6,12 +6,10 @@
6
6
  "editor.defaultFormatter": "charliermarsh.ruff",
7
7
  "editor.formatOnSave": true
8
8
  },
9
- "python.defaultInterpreterPath": "{{ venvName }}/bin/python",
10
9
  "python.autoComplete.extraPaths": [{% for folder in pythonSrcFolders %}{% if loop.index > 1 %},{% endif %}
11
10
  "{{folder}}"{% endfor %}
12
11
  ],
13
12
  "cSpell.words": [
14
- "isort",
15
13
  "noqa",
16
14
  "pycache",
17
15
  "pylint",
File without changes
File without changes
@@ -0,0 +1,9 @@
1
+ def some_sample_function(a: int, b: int) -> int:
2
+ """
3
+ Sample function that adds two integers.
4
+
5
+ :param a: The first integer.
6
+ :param b: The second integer.
7
+ :return: The sum of a and b.
8
+ """
9
+ return a + b
@@ -0,0 +1,8 @@
1
+ from pytest_multilog import TestHelper
2
+
3
+ from {{python_module}}.sample import some_sample_function
4
+
5
+
6
+ class TestSample(TestHelper):
7
+ def test_sample_function(self):
8
+ assert some_sample_function(45, 56) == 45 + 56
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nmk-python
3
- Version: 1.9.1
3
+ Version: 1.10.1
4
4
  Summary: Python plugin for nmk build system
5
5
  Author: The dynod project
6
6
  Maintainer: The dynod project
@@ -1,7 +1,7 @@
1
1
  nmk_python/__init__.py,sha256=EouCWXbAeObby1vOCx0Vx_WaGC2fEEFDMCen3JZt4TU,446
2
2
  nmk_python/badges.yml,sha256=LzElZecCXKxdF-oPkvIwfnbQlOcAM_zUj6MelClmAug,749
3
- nmk_python/build.py,sha256=nBqyMcZXhOjnMBocUooL1rM9BJyPX42A6nGbwlB5dRg,12224
4
- nmk_python/build.yml,sha256=8CWVacVv3r3pbvuRkaLQbH1aTO-oK4U0hAO9SgDTfFA,5726
3
+ nmk_python/build.py,sha256=K-ZPBSN0YgWQqS4Nz2tRg-y2zTFvcutDiNR7Ii1NrMY,12979
4
+ nmk_python/build.yml,sha256=bl1ttXjW7av5JfI8daBLF0jfUHbA4S1cy4Ym90BQ2T8,5942
5
5
  nmk_python/doc.yml,sha256=12amAlYylH7JAHaqBIOoEZ_LrXY_bPNKuHrrwUkIj8w,932
6
6
  nmk_python/files.py,sha256=K6Y-XKXuf8jh4x333Qgj6G1MyB-BgZ5Kd2-XCZhsfR4,2000
7
7
  nmk_python/files.yml,sha256=jlp87gW9rTASUnsy7id7VWanaMUMN_py82bMa2adniM,813
@@ -13,19 +13,26 @@ nmk_python/tests.py,sha256=DLUqTYhMbRupD5iK-nMnEM0GbfPPYgOp1wKHa_OCL7I,1391
13
13
  nmk_python/tests.yml,sha256=by_Ml1JXjgt1-J96AMp-6gwhISVFVylRZowUvaMkfpk,1636
14
14
  nmk_python/version.py,sha256=fLpOWdujYwlJB7XhWaOGCTeg3gQaClk2YHoRkkW64dE,3109
15
15
  nmk_python/version.yml,sha256=WpZyQ2mChmvA_6eVb_Yp6ZaFIkX6oINxWBhKgb8h4GE,833
16
+ nmk_python/_buildenv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ nmk_python/_buildenv/template.py,sha256=avDeQuMSYHTiTwAgLbrpTPZ6bSaEqjCZDkcpzFxNt88,4568
16
18
  nmk_python/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
19
  nmk_python/backends/build_backend.py,sha256=WO0wZaxGdPna4K2yK7pNLtZX3cKf6atLLa00931N43Y,1400
18
20
  nmk_python/backends/factory.py,sha256=NMYByORffwSSIjeNMLkOnwh6x1xhJQVhoV-0rSooq6Q,953
19
21
  nmk_python/backends/pip_build_backend.py,sha256=4MGYghBeMjZhUlKTwE0svSHArYwOAaK1I6_gmeNnwaI,1698
20
- nmk_python/backends/uv_build_backend.py,sha256=QpN5nMm_QhnKzoHQcX4769OOQG6NqOD2ctYXyH2MI7A,1880
22
+ nmk_python/backends/uv_build_backend.py,sha256=cIQwKVsYWHlVQCmHWjjoC-3aRmWiHK55VSGexQbn_vw,1963
21
23
  nmk_python/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
24
  nmk_python/templates/build.toml.jinja,sha256=6F1Kdb32JVBWEitxLC7AsUdhx2VTyQEyWhhSb7n3oBs,1770
23
25
  nmk_python/templates/pytest.toml.jinja,sha256=zQ3SRWnF23Omxm7zInE54j0l3OyjXSOn5pQ5Pak8Boo,641
24
- nmk_python/templates/python-settings.json.jinja,sha256=jYXSy96cX9X9GIHoF7XiZDzd4P2GOlMisAVWW626WF4,749
26
+ nmk_python/templates/python-settings.json.jinja,sha256=v-GlXJSGdtfaEZIinSC_aT54rlKArFe1RZ-BgPdbANM,666
25
27
  nmk_python/templates/python-test-debug-launch.json.jinja,sha256=J_xju2EpHNXvgvqBxlf99p7g-ZMh3xE-_2r7o_57gpU,364
26
28
  nmk_python/templates/ruff.toml.jinja,sha256=DTHe1ixK1SBY8d2xBCfkGz89HzjAoMO7Ogs12AY1i4Y,346
27
- nmk_python-1.9.1.dist-info/licenses/LICENSE,sha256=PROo9EW7wP6jmSr_90OluItAsIB411b_CAqEBioMKpI,1074
28
- nmk_python-1.9.1.dist-info/METADATA,sha256=FN-Sm5fDeJ-fKF_Zt5-EbN65960FG_EVnm-EwISt3B4,3148
29
- nmk_python-1.9.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
30
- nmk_python-1.9.1.dist-info/top_level.txt,sha256=MCb5w_hoOZ0kk3Dajxrd9Pz6lZ3pyuS6TQCRA3vddTo,11
31
- nmk_python-1.9.1.dist-info/RECORD,,
29
+ nmk_python/templates/src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ nmk_python/templates/src/__init__.py.jinja,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ nmk_python/templates/src/sample.py.jinja,sha256=OOTps7EjviwYFCIb5GpMHcidxhBY5NLQVlcFLqxuxNU,227
32
+ nmk_python/templates/src/test_sample.py.jinja,sha256=u-ShBoKDF3se9KvgQ1SzO4NwymjqNowwURF4Q1oR3wo,221
33
+ nmk_python-1.10.1.dist-info/licenses/LICENSE,sha256=PROo9EW7wP6jmSr_90OluItAsIB411b_CAqEBioMKpI,1074
34
+ nmk_python-1.10.1.dist-info/METADATA,sha256=7_h01aDokzIuXy7tl3SN5Z0APbtsAroZVR_FNNcPAVk,3149
35
+ nmk_python-1.10.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
36
+ nmk_python-1.10.1.dist-info/entry_points.txt,sha256=QLXIIXl6wODHDnVkh7KuiLv_XzfFtNfdWwpxyB675ak,88
37
+ nmk_python-1.10.1.dist-info/top_level.txt,sha256=MCb5w_hoOZ0kk3Dajxrd9Pz6lZ3pyuS6TQCRA3vddTo,11
38
+ nmk_python-1.10.1.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [buildenv_template]
2
+ nmk.python = nmk_python._buildenv.template:NmkPythonProjectTemplate