copier-python 0.20.0__tar.gz → 0.20.1__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.
Files changed (60) hide show
  1. copier_python-0.20.1/AGENTS.md +30 -0
  2. {copier_python-0.20.0 → copier_python-0.20.1}/CONTRIBUTING.md +12 -0
  3. {copier_python-0.20.0 → copier_python-0.20.1}/PKG-INFO +1 -1
  4. {copier_python-0.20.0 → copier_python-0.20.1}/pyproject.toml +1 -0
  5. {copier_python-0.20.0 → copier_python-0.20.1}/tests/conftest.py +3 -5
  6. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__snapshots__/test_pre_commit.ambr +2 -2
  7. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_agents.py +2 -2
  8. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_commit_check.py +2 -2
  9. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_contributing.py +5 -3
  10. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_docs.py +4 -2
  11. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_license.py +8 -4
  12. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_pre_commit.py +2 -2
  13. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_pyproject.py +4 -2
  14. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_readme.py +4 -2
  15. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_structure.py +12 -6
  16. {copier_python-0.20.0 → copier_python-0.20.1}/tests/utils.py +27 -12
  17. copier_python-0.20.0/AGENTS.md +0 -9
  18. {copier_python-0.20.0 → copier_python-0.20.1}/.gitignore +0 -0
  19. {copier_python-0.20.0 → copier_python-0.20.1}/LICENSE +0 -0
  20. {copier_python-0.20.0 → copier_python-0.20.1}/README.md +0 -0
  21. {copier_python-0.20.0 → copier_python-0.20.1}/copier_python/__init__.py +0 -0
  22. {copier_python-0.20.0 → copier_python-0.20.1}/copier_python/__main__.py +0 -0
  23. {copier_python-0.20.0 → copier_python-0.20.1}/copier_python/py.typed +0 -0
  24. {copier_python-0.20.0 → copier_python-0.20.1}/copier_python/repo.py +0 -0
  25. {copier_python-0.20.0 → copier_python-0.20.1}/copier_python/update.py +0 -0
  26. {copier_python-0.20.0 → copier_python-0.20.1}/docs/contributing.md +0 -0
  27. {copier_python-0.20.0 → copier_python-0.20.1}/docs/development/requirements.md +0 -0
  28. {copier_python-0.20.0 → copier_python-0.20.1}/docs/development/updates.md +0 -0
  29. {copier_python-0.20.0 → copier_python-0.20.1}/docs/development/workflow.md +0 -0
  30. {copier_python-0.20.0 → copier_python-0.20.1}/docs/index.md +0 -0
  31. {copier_python-0.20.0 → copier_python-0.20.1}/docs/license.md +0 -0
  32. {copier_python-0.20.0 → copier_python-0.20.1}/docs/project-creation.md +0 -0
  33. {copier_python-0.20.0 → copier_python-0.20.1}/docs/project-development.md +0 -0
  34. {copier_python-0.20.0 → copier_python-0.20.1}/docs/project-release.md +0 -0
  35. {copier_python-0.20.0 → copier_python-0.20.1}/docs/project-setup.md +0 -0
  36. {copier_python-0.20.0 → copier_python-0.20.1}/docs/project-updates.md +0 -0
  37. {copier_python-0.20.0 → copier_python-0.20.1}/docs/releasing.md +0 -0
  38. {copier_python-0.20.0 → copier_python-0.20.1}/docs/requirements.md +0 -0
  39. {copier_python-0.20.0 → copier_python-0.20.1}/docs/setup.md +0 -0
  40. {copier_python-0.20.0 → copier_python-0.20.1}/tests/__init__.py +0 -0
  41. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__init__.py +0 -0
  42. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__snapshots__/test_agents.ambr +0 -0
  43. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__snapshots__/test_compose.ambr +0 -0
  44. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__snapshots__/test_contributing.ambr +0 -0
  45. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__snapshots__/test_dockerfile.ambr +0 -0
  46. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__snapshots__/test_docs.ambr +0 -0
  47. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__snapshots__/test_license.ambr +0 -0
  48. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__snapshots__/test_mise_toml.ambr +0 -0
  49. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__snapshots__/test_pyproject.ambr +0 -0
  50. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__snapshots__/test_readme.ambr +0 -0
  51. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__snapshots__/test_workflows.ambr +0 -0
  52. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/__snapshots__/test_zensical.ambr +0 -0
  53. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_compose.py +0 -0
  54. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_dockerfile.py +0 -0
  55. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_mise_toml.py +0 -0
  56. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_template.py +0 -0
  57. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_workflows.py +0 -0
  58. {copier_python-0.20.0 → copier_python-0.20.1}/tests/template/test_zensical.py +0 -0
  59. {copier_python-0.20.0 → copier_python-0.20.1}/tests/test_update.py +0 -0
  60. {copier_python-0.20.0 → copier_python-0.20.1}/tests/test_version.py +0 -0
@@ -0,0 +1,30 @@
1
+ # Environment/Tools
2
+
3
+ * `mise` manages dev tools and tasks, including `uv` which manages Python and dependencies.
4
+ * Use `uv add`/`uv run python` instead of bare `pip`/`python`
5
+ * `mise install`: After-clone setup (install tools, dependencies, pre-commit hooks)
6
+ * `mise run lint`: Pre-commit hooks (via `pre-commit`-compatible `prek`) including lint, format, type check (ruff, ty)
7
+ * `mise run test`: Run tests (accepts pytest arguments)
8
+ * `mise run lt`: Lint+test (no arguments)
9
+ * `mise run snapup`: Update test snapshots (syrupy, accepts pytest arguments)
10
+
11
+ # Commit conventions
12
+
13
+ * Keep commit messages concise and in plain language, so a maintainer can
14
+ quickly understand the change. Use a short subject, and add a body only when
15
+ the change needs explaining, in a few lines about why. Don't list changed
16
+ files, restate the diff, or report test results.
17
+ * If a commit contains code or text largely generated by an LLM, add an
18
+ `Assisted-by: <tool>:<model>` trailer, for example with `git commit --trailer`.
19
+ * Don't add `Co-authored-by` or `Signed-off-by` lines for LLM tools, links to
20
+ LLM sessions, or promotional lines such as "Generated with [...]".
21
+
22
+ # Submitting contributions
23
+
24
+ * You may commit locally without asking. Before submitting anything, such as
25
+ pushing commits or creating or editing a pull request, issue, or comment,
26
+ show the user (who is the contributor) exactly what will be submitted, and
27
+ wait for their explicit approval. Submit it as approved. This includes but is
28
+ not limited to commit messages, titles, and bodies.
29
+ * Keep titles and descriptions short and specific. Don't restate what the diff
30
+ already shows.
@@ -21,3 +21,15 @@ licensed under the project's license, the
21
21
  [MIT License](https://github.com/smkent/copier-python/blob/main/LICENSE),
22
22
  with no additional terms,
23
23
  and that you have the right to submit it under that license.
24
+
25
+ ## LLM use
26
+
27
+ A contributor is always the author of their contributions.
28
+ You must read, review, and understand everything you submit, including
29
+ LLM-generated code or text, and be able to explain it on request.
30
+
31
+ If a commit contains code or text largely generated by an LLM, add an
32
+ `Assisted-by: <tool>:<model>` trailer to its message. This can be done
33
+ automatically with `git commit --trailer="Assisted-by: <tool>:<model>"`.
34
+
35
+ Do not use `Co-authored-by:` for LLM attribution. LLMs are tools, not authors.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: copier-python
3
- Version: 0.20.0
3
+ Version: 0.20.1
4
4
  Summary: Copier template for Python projects with modern tooling
5
5
  Project-URL: Homepage, https://smkent.github.io/copier-python
6
6
  Project-URL: Repository, https://github.com/smkent/copier-python
@@ -45,6 +45,7 @@ Issues = "https://github.com/smkent/copier-python/issues"
45
45
  [dependency-groups]
46
46
  dev = [
47
47
  "bump-my-version>=1.3.0",
48
+ "commit-check>=2.18",
48
49
  "copier>=9",
49
50
  "poethepoet>=0.46",
50
51
  "pysentry-rs>=0.4",
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
  import subprocess
4
4
  import warnings
5
5
  from functools import partial
6
- from pathlib import Path
7
6
  from typing import TYPE_CHECKING, Any
8
7
 
9
8
  import copier
@@ -12,12 +11,11 @@ import yaml
12
11
 
13
12
  from copier_python.__main__ import setup_env
14
13
 
15
- from .utils import DisallowCallable
14
+ from .utils import DisallowCallable, template
16
15
 
17
16
  if TYPE_CHECKING:
18
17
  from collections.abc import Callable, Iterator
19
-
20
- TEMPLATE_ROOT = Path(__file__).parent.parent
18
+ from pathlib import Path
21
19
 
22
20
  DEFAULT_DATA: dict[str, Any] = {
23
21
  "project_name": "PKFire",
@@ -84,7 +82,7 @@ def session_render_template(
84
82
  )
85
83
  with disallow_subprocess.pause():
86
84
  copier.run_copy(
87
- src_path=str(TEMPLATE_ROOT),
85
+ src_path=str(template.dir),
88
86
  dst_path=str(worktree),
89
87
  data=data,
90
88
  vcs_ref=vcs_ref,
@@ -52,7 +52,7 @@
52
52
  pass_filenames: false
53
53
  - id: commit-check
54
54
  name: commit-check
55
- entry: uv run commit-check --message
55
+ entry: uv run commit-check --no-banner --message
56
56
  language: system
57
57
  stages: [commit-msg]
58
58
 
@@ -163,7 +163,7 @@
163
163
  pass_filenames: false
164
164
  - id: commit-check
165
165
  name: commit-check
166
- entry: uv run commit-check --message
166
+ entry: uv run commit-check --no-banner --message
167
167
  language: system
168
168
  stages: [commit-msg]
169
169
 
@@ -6,11 +6,11 @@ from pathlib import Path
6
6
  import pytest
7
7
  from syrupy.assertion import SnapshotAssertion
8
8
 
9
- from tests.utils import choices
9
+ from tests.utils import template
10
10
 
11
11
 
12
12
  @pytest.mark.parametrize(
13
- "llm_contribution_policy", choices["llm_contribution_policy"]
13
+ "llm_contribution_policy", template.choices.llm_contribution_policy
14
14
  )
15
15
  def test_agents(
16
16
  render_template: Callable[..., Path],
@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING
4
4
 
5
5
  import pytest
6
6
 
7
- from tests.utils import TEMPLATE_ROOT
7
+ from tests.utils import template
8
8
 
9
9
  if TYPE_CHECKING:
10
10
  from collections.abc import Callable
@@ -25,5 +25,5 @@ def test_commit_check_config(
25
25
  ) -> None:
26
26
  rendered = render_template(project_visibility=project_visibility)
27
27
  assert (rendered / config_path).read_text() == (
28
- TEMPLATE_ROOT / "includes" / "commit-check.toml"
28
+ template.dir / "includes" / "commit-check.toml"
29
29
  ).read_text()
@@ -6,7 +6,7 @@ from pathlib import Path
6
6
  import pytest
7
7
  from syrupy.assertion import SnapshotAssertion
8
8
 
9
- from tests.utils import choices
9
+ from tests.utils import template
10
10
 
11
11
 
12
12
  @pytest.mark.parametrize(
@@ -14,7 +14,7 @@ from tests.utils import choices
14
14
  [pytest.param(True, id="docs"), pytest.param(False, id="no_docs")],
15
15
  )
16
16
  @pytest.mark.parametrize(
17
- "llm_contribution_policy", choices["llm_contribution_policy"]
17
+ "llm_contribution_policy", template.choices.llm_contribution_policy
18
18
  )
19
19
  def test_contributing_features(
20
20
  render_template: Callable[..., Path],
@@ -30,7 +30,9 @@ def test_contributing_features(
30
30
  assert (rendered / "CONTRIBUTING.md").read_text() == snapshot
31
31
 
32
32
 
33
- @pytest.mark.parametrize("copyright_license", choices["copyright_license"])
33
+ @pytest.mark.parametrize(
34
+ "copyright_license", template.choices.copyright_license
35
+ )
34
36
  def test_contributing_license(
35
37
  render_template: Callable[..., Path],
36
38
  snapshot: SnapshotAssertion,
@@ -6,7 +6,7 @@ from pathlib import Path
6
6
  import pytest
7
7
  from syrupy.assertion import SnapshotAssertion
8
8
 
9
- from tests.utils import choices
9
+ from tests.utils import template
10
10
 
11
11
 
12
12
  @pytest.mark.parametrize(
@@ -66,7 +66,9 @@ def test_docs_development_features(
66
66
  ).read_text() == snapshot
67
67
 
68
68
 
69
- @pytest.mark.parametrize("copyright_license", choices["copyright_license"])
69
+ @pytest.mark.parametrize(
70
+ "copyright_license", template.choices.copyright_license
71
+ )
70
72
  def test_docs_license(
71
73
  render_template: Callable[..., Path],
72
74
  snapshot: SnapshotAssertion,
@@ -7,10 +7,12 @@ import pytest
7
7
  import yaml
8
8
  from syrupy.assertion import SnapshotAssertion
9
9
 
10
- from tests.utils import TEMPLATE_ROOT, choices
10
+ from tests.utils import template
11
11
 
12
12
 
13
- @pytest.mark.parametrize("copyright_license", choices["copyright_license"])
13
+ @pytest.mark.parametrize(
14
+ "copyright_license", template.choices.copyright_license
15
+ )
14
16
  def test_license(
15
17
  render_template: Callable[..., Path],
16
18
  snapshot: SnapshotAssertion,
@@ -35,10 +37,12 @@ def test_license_default(
35
37
  )
36
38
 
37
39
 
38
- @pytest.mark.parametrize("copyright_license", choices["copyright_license"])
40
+ @pytest.mark.parametrize(
41
+ "copyright_license", template.choices.copyright_license
42
+ )
39
43
  def test_license_choices_have_templates(copyright_license: str) -> None:
40
44
  assert (
41
- TEMPLATE_ROOT / "includes" / "licenses" / copyright_license
45
+ template.dir / "includes" / "licenses" / copyright_license
42
46
  ).is_file()
43
47
 
44
48
 
@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING
4
4
 
5
5
  import pytest
6
6
 
7
- from tests.utils import choices
7
+ from tests.utils import template
8
8
 
9
9
  if TYPE_CHECKING:
10
10
  from collections.abc import Callable
@@ -14,7 +14,7 @@ if TYPE_CHECKING:
14
14
 
15
15
 
16
16
  @pytest.mark.parametrize(
17
- "llm_contribution_policy", choices["llm_contribution_policy"]
17
+ "llm_contribution_policy", template.choices.llm_contribution_policy
18
18
  )
19
19
  def test_pre_commit_config(
20
20
  render_template: Callable[..., Path],
@@ -6,7 +6,7 @@ from pathlib import Path
6
6
  import pytest
7
7
  from syrupy.assertion import SnapshotAssertion
8
8
 
9
- from tests.utils import choices
9
+ from tests.utils import template
10
10
 
11
11
 
12
12
  @pytest.mark.parametrize("project_visibility", ["public", "private"])
@@ -63,7 +63,9 @@ def test_pyproject_versions(
63
63
  assert (rendered / "pyproject.toml").read_text() == snapshot
64
64
 
65
65
 
66
- @pytest.mark.parametrize("copyright_license", choices["copyright_license"])
66
+ @pytest.mark.parametrize(
67
+ "copyright_license", template.choices.copyright_license
68
+ )
67
69
  def test_pyproject_licenses(
68
70
  render_template: Callable[..., Path],
69
71
  snapshot: SnapshotAssertion,
@@ -6,7 +6,7 @@ from pathlib import Path
6
6
  import pytest
7
7
  from syrupy.assertion import SnapshotAssertion
8
8
 
9
- from tests.utils import choices
9
+ from tests.utils import template
10
10
 
11
11
 
12
12
  @pytest.mark.parametrize(
@@ -41,7 +41,9 @@ def test_readme_features(
41
41
 
42
42
 
43
43
  @pytest.mark.parametrize("project_visibility", ["public", "private"])
44
- @pytest.mark.parametrize("copyright_license", choices["copyright_license"])
44
+ @pytest.mark.parametrize(
45
+ "copyright_license", template.choices.copyright_license
46
+ )
45
47
  def test_readme_project_visibility(
46
48
  render_template: Callable[..., Path],
47
49
  snapshot: SnapshotAssertion,
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Any
6
6
 
7
7
  import pytest
8
8
 
9
- from tests.utils import choices
9
+ from tests.utils import template
10
10
 
11
11
  if TYPE_CHECKING:
12
12
  from collections.abc import Callable
@@ -48,8 +48,10 @@ def structure_test(
48
48
  return StructureTest(render_template=render_template)
49
49
 
50
50
 
51
- @pytest.mark.parametrize("project_type", choices["project_type"])
52
- @pytest.mark.parametrize("project_visibility", choices["project_visibility"])
51
+ @pytest.mark.parametrize("project_type", template.choices.project_type)
52
+ @pytest.mark.parametrize(
53
+ "project_visibility", template.choices.project_visibility
54
+ )
53
55
  @pytest.mark.parametrize(
54
56
  "enable_coverage",
55
57
  [pytest.param(True, id="coverage"), pytest.param(False, id="no_coverage")],
@@ -140,7 +142,9 @@ def test_structure(
140
142
  structure_test(case)
141
143
 
142
144
 
143
- @pytest.mark.parametrize("copyright_license", choices["copyright_license"])
145
+ @pytest.mark.parametrize(
146
+ "copyright_license", template.choices.copyright_license
147
+ )
144
148
  def test_structure_license(
145
149
  structure_test: StructureTest,
146
150
  copyright_license: str,
@@ -157,9 +161,11 @@ def test_structure_license(
157
161
 
158
162
 
159
163
  @pytest.mark.parametrize(
160
- "llm_contribution_policy", choices["llm_contribution_policy"]
164
+ "llm_contribution_policy", template.choices.llm_contribution_policy
165
+ )
166
+ @pytest.mark.parametrize(
167
+ "project_visibility", template.choices.project_visibility
161
168
  )
162
- @pytest.mark.parametrize("project_visibility", choices["project_visibility"])
163
169
  def test_structure_contributing(
164
170
  structure_test: StructureTest,
165
171
  project_visibility: str,
@@ -3,7 +3,9 @@ from __future__ import annotations
3
3
  import sys
4
4
  from contextlib import contextmanager
5
5
  from dataclasses import dataclass, field
6
+ from functools import cached_property
6
7
  from pathlib import Path
8
+ from types import SimpleNamespace
7
9
  from typing import TYPE_CHECKING, Any
8
10
  from unittest.mock import MagicMock, patch
9
11
 
@@ -20,9 +22,6 @@ if TYPE_CHECKING:
20
22
  import pytest
21
23
 
22
24
 
23
- TEMPLATE_ROOT = Path(__file__).parent.parent
24
-
25
-
26
25
  @dataclass
27
26
  class DisallowCallable:
28
27
  request: pytest.FixtureRequest
@@ -69,12 +68,28 @@ class DisallowCallable:
69
68
  self.mock_attr.assert_not_called()
70
69
 
71
70
 
72
- choices = {
73
- k: list(choices.values()) if isinstance(choices, dict) else choices
74
- for k, v in yaml.safe_load(
75
- (TEMPLATE_ROOT / "copier.yaml").read_text()
76
- ).items()
77
- if isinstance(v, dict)
78
- and (choices := v.get("choices"))
79
- and isinstance(choices, (dict, list))
80
- }
71
+ class Template:
72
+ @cached_property
73
+ def dir(self) -> Path:
74
+ return Path(__file__).parent.parent
75
+
76
+ @cached_property
77
+ def config(self) -> dict[str, Any]:
78
+ return yaml.safe_load((self.dir / "copier.yaml").read_text())
79
+
80
+ @cached_property
81
+ def choices(self) -> SimpleNamespace:
82
+ return SimpleNamespace(
83
+ **{
84
+ k: list(choices.values())
85
+ if isinstance(choices, dict)
86
+ else choices
87
+ for k, v in self.config.items()
88
+ if isinstance(v, dict)
89
+ and (choices := v.get("choices"))
90
+ and isinstance(choices, (dict, list))
91
+ }
92
+ )
93
+
94
+
95
+ template = Template()
@@ -1,9 +0,0 @@
1
- # Environment/Tools
2
-
3
- * `mise` manages dev tools and tasks, including `uv` which manages Python and dependencies.
4
- * Use `uv add`/`uv run python` instead of bare `pip`/`python`
5
- * `mise install`: After-clone setup (install tools, dependencies, pre-commit hooks)
6
- * `mise run lint`: Pre-commit hooks (via `pre-commit`-compatible `prek`) including lint, format, type check (ruff, ty)
7
- * `mise run test`: Run tests (accepts pytest arguments)
8
- * `mise run lt`: Lint+test (no arguments)
9
- * `mise run snapup`: Update test snapshots (syrupy, accepts pytest arguments)
File without changes
File without changes