csspin-python 2.1.0__py3-none-any.whl → 3.0.0__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.
@@ -96,9 +96,6 @@ python:
96
96
  site_packages:
97
97
  type: path internal
98
98
  help: The path to the virtual environments site-packages directory.
99
- devpackages:
100
- type: list
101
- help: A list of packages that will be editable installed
102
99
  requirements:
103
100
  type: list
104
101
  help: |
@@ -106,18 +103,8 @@ python:
106
103
  have to be installed into the project's virtual environment.
107
104
  This excludes requirements stated as 'install_requires' in
108
105
  setup.py/setup.cfg.
109
- current_package:
110
- type: object
111
- help: Install configuration of the current python project
112
- properties:
113
- install:
114
- type: bool
115
- help: |
116
- Property to determine whether the current package should
117
- get installed or not.
118
- extras:
119
- type: list
120
- help: The extras of the current package to install.
106
+ Note that editable installs with ``-e`` or requirement files
107
+ with ``-r`` can also be used here.
121
108
  index_url:
122
109
  type: str
123
110
  help: |
@@ -157,3 +144,9 @@ python:
157
144
  index:
158
145
  type: str
159
146
  help: The Codeartifact repository index (e.g. "16.0/simple").
147
+ client_id:
148
+ type: str
149
+ help: The OIDC client ID to use.
150
+ role_arn:
151
+ type: str
152
+ help: The role ARN to assume when authenticating.
csspin_python/radon.py CHANGED
@@ -18,8 +18,10 @@
18
18
  """Module implementing the radon plugin for spin"""
19
19
 
20
20
  import logging
21
+ from typing import Iterable
21
22
 
22
23
  from csspin import config, info, option, sh, task
24
+ from csspin.tree import ConfigTree
23
25
 
24
26
  defaults = config(
25
27
  exe="radon",
@@ -36,20 +38,20 @@ defaults = config(
36
38
 
37
39
  @task()
38
40
  def radon(
39
- cfg,
40
- allsource: option(
41
+ cfg: ConfigTree,
42
+ allsource: option( # type: ignore[valid-type]
41
43
  "--all", # noqa: F821
42
44
  "allsource", # noqa: F821
43
45
  is_flag=True,
44
46
  help="Run for all src- and test-files.", # noqa: F722,F821
45
47
  ),
46
- args,
47
- ):
48
+ args: Iterable[str],
49
+ ) -> None:
48
50
  """Run radon to measure code complexity."""
49
51
  if allsource:
50
- files = ("{spin.project_root}/src", "{spin.project_root}/tests")
52
+ files = ["{spin.project_root}/src", "{spin.project_root}/tests"]
51
53
  else:
52
- files = args
54
+ files = list(args)
53
55
  if not files and hasattr(cfg, "vcs") and hasattr(cfg.vcs, "modified"):
54
56
  info("Found modified files.")
55
57
  files = cfg.vcs.modified
@@ -0,0 +1,187 @@
1
+ # -*- mode: python; coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2025 CONTACT Software GmbH
4
+ # https://www.contact-software.com/
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ """
19
+ Plugin to replace certain things of the csspin_python.python plugin with the
20
+ tool ``uv``. Can only be used if the ``uv`` extra of csspin_python has been
21
+ installed.
22
+ """
23
+
24
+ import shutil
25
+ import subprocess
26
+ from typing import Union
27
+
28
+ try:
29
+ import tomllib
30
+ except ImportError:
31
+ # Fallback for spin has been installed with python < 3.11
32
+ import tomli as tomllib
33
+
34
+ import tomli_w
35
+ from csspin import Command, Path, Verbosity, config, die, info, interpolate1, setenv
36
+ from csspin.tree import ConfigTree
37
+
38
+ from csspin_python.python import SimpleProvisioner
39
+
40
+ defaults = config(
41
+ enabled=False,
42
+ uv_python_data="{spin.data}/uv_python",
43
+ uv_toml_path="{python.venv}/uv.toml",
44
+ requires=config(
45
+ spin=[
46
+ "csspin_python.python",
47
+ ],
48
+ ),
49
+ )
50
+
51
+
52
+ def venv_hook(cfg: ConfigTree) -> None:
53
+ """Things to do right after venv creation."""
54
+ _configure_uv_toml(cfg)
55
+ setenv(UV_CONFIG_FILE=cfg.uv_provisioner.uv_toml_path)
56
+
57
+
58
+ def configure(cfg: ConfigTree) -> None:
59
+ """Configure the uv_provisioner plugin."""
60
+ if interpolate1(cfg.uv_provisioner.enabled).lower() == "true":
61
+ cfg.python.provisioner = SimpleUvProvisioner(cfg)
62
+ setenv(
63
+ UV_PYTHON_INSTALL_DIR=interpolate1(cfg.uv_provisioner.uv_python_data),
64
+ )
65
+ if cfg.python.use:
66
+ cfg.python.interpreter = shutil.which(interpolate1(cfg.python.interpreter))
67
+ else:
68
+ if interpreter_path := _get_uv_python(cfg, True):
69
+ cfg.python.interpreter = interpreter_path
70
+ else:
71
+ # No uv provisioned python found, set to an empty string to
72
+ # force provisioning
73
+ cfg.python.interpreter = ""
74
+
75
+ if cfg.python.aws_auth.enabled:
76
+ # In case we use aws_auth the index-url might have changed
77
+ _update_index_url_in_toml(cfg)
78
+
79
+
80
+ def _get_uv_python(cfg: ConfigTree, ignore_errors: bool = False) -> Union[Path, None]:
81
+ """Use uv to find its provisioned python interpreter."""
82
+ # We cannot put this import top-level as "spin cleanup" might not work
83
+ # otherwise.
84
+ from uv import find_uv_bin
85
+
86
+ cmd = [
87
+ find_uv_bin(),
88
+ "python",
89
+ "find",
90
+ "--no-project",
91
+ "--system",
92
+ "--managed-python",
93
+ cfg.python.version,
94
+ ]
95
+ try:
96
+ out = subprocess.check_output(
97
+ cmd, encoding="utf-8", stderr=subprocess.DEVNULL if ignore_errors else None
98
+ )
99
+ interpreter = out.strip()
100
+ return Path(interpreter)
101
+ except subprocess.CalledProcessError as ex:
102
+ if not ignore_errors:
103
+ die(ex)
104
+ return None
105
+
106
+
107
+ class SimpleUvProvisioner(SimpleProvisioner):
108
+ """
109
+ Drop-in replacement for the SimpleProvisioner that uses ``uv`` for creating
110
+ the environment and installing the requirements.
111
+
112
+ Especially when installing Python packages, the ``SimpleUvProvisioner`` is
113
+ much faster than the ``SimpleProvisioner``.
114
+ """
115
+
116
+ def __init__(self, cfg: ConfigTree) -> None:
117
+ super().__init__(cfg)
118
+
119
+ from uv import find_uv_bin
120
+
121
+ uv_bin = find_uv_bin()
122
+
123
+ if cfg.verbosity == Verbosity.QUIET:
124
+ verbosity = "-q"
125
+ elif cfg.verbosity == Verbosity.DEBUG:
126
+ verbosity = "-v"
127
+ else:
128
+ verbosity = None
129
+
130
+ self._uv_cmd = Command(
131
+ uv_bin,
132
+ verbosity,
133
+ )
134
+ self._install_command = Command(
135
+ *self._uv_cmd._cmd,
136
+ "pip",
137
+ "install",
138
+ )
139
+
140
+ def provision_python(self, cfg: ConfigTree) -> None:
141
+ self._uv_cmd(
142
+ "python",
143
+ "install",
144
+ cfg.python.version,
145
+ "--no-bin",
146
+ "--no-registry",
147
+ )
148
+ cfg.python.interpreter = _get_uv_python(cfg)
149
+ info(f"Using '{cfg.python.interpreter}' as interpreter")
150
+
151
+ def provision_venv(self, cfg: ConfigTree) -> None:
152
+ setenv(UV_PROJECT_ENVIRONMENT=cfg.python.venv)
153
+ self._uv_cmd(
154
+ "venv",
155
+ f"--python={cfg.python.interpreter}",
156
+ cfg.python.venv,
157
+ )
158
+
159
+ def prerequisites(self, cfg: ConfigTree) -> None:
160
+ self._uv_cmd("pip", "install", "pip")
161
+
162
+
163
+ def _configure_uv_toml(cfg: ConfigTree) -> None:
164
+ """
165
+ Create a config file for uv, similar to the pip.conf of
166
+ csspin_python.python, since `uv` pip won't respect the pip.conf.
167
+ """
168
+ toml_content = tomllib.loads(cfg.uv_provisioner.uv_toml or "")
169
+ if "index-url" not in toml_content:
170
+ toml_content["index-url"] = cfg.python.index_url
171
+ else:
172
+ toml_content["index-url"] = toml_content.get("index-url", cfg.python.index_url)
173
+
174
+ with open(cfg.uv_provisioner.uv_toml_path, mode="wb") as fd:
175
+ tomli_w.dump(toml_content, fd)
176
+
177
+
178
+ def _update_index_url_in_toml(cfg: ConfigTree) -> None:
179
+ """
180
+ Update the index-url in the uv.toml in case it changed.
181
+ """
182
+ if (uv_toml_path := interpolate1(cfg.uv_provisioner.uv_toml_path)).exists():
183
+ with open(uv_toml_path, mode="r+b") as fd:
184
+ toml_content = tomllib.load(fd)
185
+ if toml_content.get("index-url") != cfg.python.index_url:
186
+ toml_content["index-url"] = cfg.python.index_url
187
+ tomli_w.dump(toml_content, fd)
@@ -0,0 +1,24 @@
1
+ # -*- mode: yaml; coding: utf-8 -*-
2
+ #
3
+ # Schema for the uv_provisioner plugin for spin
4
+
5
+ uv_provisioner:
6
+ type: object
7
+ help: Configuration of the csspin_python.uv plugin
8
+ properties:
9
+ enabled:
10
+ type: bool
11
+ help: |
12
+ Used to let the python plugin use the SimpleUvProvisioner to
13
+ provision the python environment.
14
+ uv_python_data:
15
+ type: path
16
+ help: |
17
+ The directory where the python interpreters uv provisions are
18
+ being stored.
19
+ uv_toml_path:
20
+ type: path
21
+ help: Path to uv's config file
22
+ uv_toml:
23
+ type: str
24
+ help: Content for uv's config file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csspin-python
3
- Version: 2.1.0
3
+ Version: 3.0.0
4
4
  Summary: Plugin-package for csspin providing Python related plugins
5
5
  Author-email: CONTACT Software GmbH <info@contact-software.com>
6
6
  Maintainer-email: Waleri Enns <waleri.enns@contact-software.com>, Benjamin Thomas Schwertfeger <benjaminthomas.schwertfeger@contact-software.com>, Fabian Hafer <fabian.hafer@contact-software.com>
@@ -20,9 +20,14 @@ Classifier: Topic :: Software Development
20
20
  Requires-Python: >=3.9
21
21
  Description-Content-Type: text/x-rst
22
22
  License-File: LICENSE
23
+ Requires-Dist: platformdirs~=4.3.8
23
24
  Requires-Dist: virtualenv
24
25
  Provides-Extra: aws-auth
25
26
  Requires-Dist: csaccess>=0.1.0; extra == "aws-auth"
27
+ Provides-Extra: uv
28
+ Requires-Dist: tomli; python_version < "3.11" and extra == "uv"
29
+ Requires-Dist: tomli-w; extra == "uv"
30
+ Requires-Dist: uv; extra == "uv"
26
31
  Dynamic: license-file
27
32
 
28
33
  |Latest Version| |Python| |License|
@@ -35,16 +40,20 @@ The following plugins are available:
35
40
  - `csspin_python.behave`: A plugin for running tests using Behave.
36
41
  - `csspin_python.debugpy`: A plugin for debugging Python code using `debugpy`_.
37
42
  - `csspin_python.devpi`: A plugin for simplified usage of `devpi`_.
38
- - `csspin_python.playwright`: A plugin for running tests using `playwright`_.
39
43
  - `csspin_python.pytest`: A plugin for running tests using pytest.
40
44
  - `csspin_python.python`: A plugin for provisioning Python environments and
41
45
  installing dependencies.
42
46
  - `csspin_python.radon`: A plugin for running `radon`_ to analyze code
43
47
  complexity.
44
48
  - `csspin_python.sphinx`: A plugin for building Sphinx documentation.
49
+ - `csspin_python.playwright`: A plugin for running tests using `playwright`_.
50
+ This plugin is deprecated, use the pytest plugin with the
51
+ 'pytest.playwright.enabled=true' setting instead.
52
+ - `csspin_python.uv_provisioner`: A plugin that uses `uv`_ to provision the Python environment.
45
53
 
46
- The package provides an ``aws_auth`` extra, that, if enabled, can
47
- authenticate to `CONTACT Software GmbH`_'s AWS Codeartifact.
54
+ The package provides an ``aws_auth`` extra, that, if enabled, can authenticate
55
+ to `CONTACT Software GmbH`_'s AWS Codeartifact. It also provides an ``uv``
56
+ extra, that is necessary for using the ``csspin_python.uv_provisioner`` plugin.
48
57
 
49
58
  Prerequisites
50
59
  -------------
@@ -107,3 +116,4 @@ tests using ``spin pytest`` and do other great things.
107
116
  .. _`devpi`: https://pypi.org/project/devpi
108
117
  .. _`playwright`: https://pypi.org/project/pytest-playwright
109
118
  .. _`radon`: https://pypi.org/project/radon
119
+ .. _`uv`: https://docs.astral.sh/uv/
@@ -0,0 +1,21 @@
1
+ csspin_python/behave.py,sha256=iJZeyIqB7V_NzTdLTZldNY9W_GGwCWkXe6WY69wpDqs,4997
2
+ csspin_python/behave_schema.yaml,sha256=8qoOCK-uTmwgRRW29urgK0X_kgn0zO0X34v89bvii2w,1241
3
+ csspin_python/debugpy.py,sha256=v0ZZopv5TNoSaFf2kiePsw9OmhBpjfOBFh0u71jTcnQ,962
4
+ csspin_python/debugpy_schema.yaml,sha256=BeH30nSirDYctkdhS9xMXUG5htj3PED_ZjmxPG5WRUc,364
5
+ csspin_python/devpi.py,sha256=C-5O_vA06CwQR4uElOw-2VH2-m001SpxowM_X6RbRwo,2352
6
+ csspin_python/devpi_schema.yaml,sha256=2gPATWjVcfvCTrGZX2FK6wH8hh9KS0XzZ35JvZeJGEU,487
7
+ csspin_python/playwright.py,sha256=oFfphLqa4AB6K9vasCUFHN0kFXu63n3ocrsqVuRp4-0,5102
8
+ csspin_python/playwright_schema.yaml,sha256=TSeR16YHa7m7bfO59F2eMV-jXcglluTJdEpUeL16saY,1178
9
+ csspin_python/pytest.py,sha256=fX50f22DYtJNNTBkAt75ki26eM0sZDcRXnwoFsKWV_M,4565
10
+ csspin_python/pytest_schema.yaml,sha256=tzXtdF6MvGC9v59EVRJFfLeMMHqPsXcFXy2zJtRECBI,1535
11
+ csspin_python/python.py,sha256=SRsl7wXkPFxEqwhjDtr-Uq80N_JNRrlD0kPMaE1gfrU,34610
12
+ csspin_python/python_schema.yaml,sha256=s8snEDJ8UdfpORgCgqbKvy0exaXlvy4U1gUwBd-Do94,5739
13
+ csspin_python/radon.py,sha256=uFqm6FEi5oWj-_XVaAm3s9cam0cUmr1_FwRf40K6xWs,1876
14
+ csspin_python/radon_schema.yaml,sha256=rlRzXw5z4XbjOVznRiUxWGP4E9hx1Jm-gGw1iQiYzE0,548
15
+ csspin_python/uv_provisioner.py,sha256=A6Di0ahCrZCO3KhYedry7JCfa5ME6h7vH4ypRBZh5UA,5907
16
+ csspin_python/uv_provisioner_schema.yaml,sha256=Y8ZNC2OMnhR8Us3WUXAXK9hMjqGWAKFJB2puX4X5XNQ,727
17
+ csspin_python-3.0.0.dist-info/licenses/LICENSE,sha256=4MAecetnRTQw5DlHtiikDSzKWO1xVLwzM5_DsPMYlnE,10172
18
+ csspin_python-3.0.0.dist-info/METADATA,sha256=NkiY16n49Q9lFYCu-emb9G1OjQlg3gEm0vW5t3EJwtE,4715
19
+ csspin_python-3.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
+ csspin_python-3.0.0.dist-info/top_level.txt,sha256=QSeglMEGbFu1z4L6MCQYwo01NgL0KojWvC4rzgMQ8gU,14
21
+ csspin_python-3.0.0.dist-info/RECORD,,
@@ -1,19 +0,0 @@
1
- csspin_python/behave.py,sha256=iA5t-vwMDhmWoo-FHaeZ6JyIzj6k4r2WLyYa2AjXyp4,4815
2
- csspin_python/behave_schema.yaml,sha256=8qoOCK-uTmwgRRW29urgK0X_kgn0zO0X34v89bvii2w,1241
3
- csspin_python/debugpy.py,sha256=v0ZZopv5TNoSaFf2kiePsw9OmhBpjfOBFh0u71jTcnQ,962
4
- csspin_python/debugpy_schema.yaml,sha256=BeH30nSirDYctkdhS9xMXUG5htj3PED_ZjmxPG5WRUc,364
5
- csspin_python/devpi.py,sha256=2NhGYzq4aVzDa_d80uItUlYM9cA0uRFQ4rvnCryxL2k,2213
6
- csspin_python/devpi_schema.yaml,sha256=2gPATWjVcfvCTrGZX2FK6wH8hh9KS0XzZ35JvZeJGEU,487
7
- csspin_python/playwright.py,sha256=nYuPjuTfGx_6QPYsUpr-eAZARyXX_hZF8D4AxeI2u1s,4003
8
- csspin_python/playwright_schema.yaml,sha256=WFMok7dB7G6L8f8y_2_RKHjGe4ww1iUUS4tqCoUI1FE,1054
9
- csspin_python/pytest.py,sha256=EwxPynyPWS72NTtIah1jUGVa7fJYY8I2_NQz0y0U7Os,2978
10
- csspin_python/pytest_schema.yaml,sha256=1bF8hNsJfV-LHUwGBBJ3GnQOZJiIQkG81DCBma2MalU,809
11
- csspin_python/python.py,sha256=du1sFA6Uh8Wp5V6sN3_iSsQNEz-OZBAJG-FdgCyvsjM,33114
12
- csspin_python/python_schema.yaml,sha256=F_PMK8D3KBvXK945b6-oRDoaxuDgxkBGqVPAJ-eFmv0,5970
13
- csspin_python/radon.py,sha256=OSV0vTz7SMMHC82jUvWsBq6vtWolOjdiZ2bBdxplVJ4,1744
14
- csspin_python/radon_schema.yaml,sha256=rlRzXw5z4XbjOVznRiUxWGP4E9hx1Jm-gGw1iQiYzE0,548
15
- csspin_python-2.1.0.dist-info/licenses/LICENSE,sha256=4MAecetnRTQw5DlHtiikDSzKWO1xVLwzM5_DsPMYlnE,10172
16
- csspin_python-2.1.0.dist-info/METADATA,sha256=-cWwMdEo8x0I1_vcEAjiCO5DC79Y-ymGXro6Qig7Q4s,4174
17
- csspin_python-2.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
18
- csspin_python-2.1.0.dist-info/top_level.txt,sha256=QSeglMEGbFu1z4L6MCQYwo01NgL0KojWvC4rzgMQ8gU,14
19
- csspin_python-2.1.0.dist-info/RECORD,,