ducktools-classbuilder 0.9.0__tar.gz → 0.10.0__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.

Potentially problematic release.


This version of ducktools-classbuilder might be problematic. Click here for more details.

Files changed (97) hide show
  1. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/.github/workflows/auto_test.yml +5 -5
  2. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/.github/workflows/publish_to_pypi.yml +2 -2
  3. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/.github/workflows/publish_to_testpypi.yml +2 -2
  4. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/PKG-INFO +8 -17
  5. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs/tutorial.md +5 -6
  6. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs_code/docs_ex9_annotated.py +14 -14
  7. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs_code/tutorial_code.py +5 -7
  8. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/pyproject.toml +28 -8
  9. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/src/ducktools/classbuilder/__init__.py +191 -67
  10. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/src/ducktools/classbuilder/__init__.pyi +18 -9
  11. ducktools_classbuilder-0.10.0/src/ducktools/classbuilder/_version.py +2 -0
  12. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/src/ducktools/classbuilder/annotations.py +2 -13
  13. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/src/ducktools/classbuilder/prefab.py +9 -3
  14. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/src/ducktools/classbuilder/prefab.pyi +3 -0
  15. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/src/ducktools_classbuilder.egg-info/PKG-INFO +8 -17
  16. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/src/ducktools_classbuilder.egg-info/SOURCES.txt +20 -32
  17. ducktools_classbuilder-0.10.0/src/ducktools_classbuilder.egg-info/requires.txt +5 -0
  18. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/tests/annotations/test_annotated.py +5 -3
  19. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/tests/annotations/test_annotations_module.py +7 -7
  20. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/tests/annotations/test_future_annotations.py +3 -0
  21. ducktools_classbuilder-0.10.0/tests/conftest.py +20 -0
  22. ducktools_classbuilder-0.10.0/tests/helpers/utils.py +7 -0
  23. {ducktools_classbuilder-0.9.0/tests/prefab/dynamic → ducktools_classbuilder-0.10.0/tests/prefab}/test_construction.py +4 -0
  24. ducktools_classbuilder-0.10.0/tests/prefab/test_creation.py +300 -0
  25. ducktools_classbuilder-0.10.0/tests/prefab/test_dunders.py +188 -0
  26. {ducktools_classbuilder-0.9.0/tests/prefab/shared → ducktools_classbuilder-0.10.0/tests/prefab}/test_funcs.py +22 -8
  27. {ducktools_classbuilder-0.9.0/tests/prefab/shared → ducktools_classbuilder-0.10.0/tests/prefab}/test_hint_syntax.py +23 -6
  28. ducktools_classbuilder-0.10.0/tests/prefab/test_inheritance.py +123 -0
  29. {ducktools_classbuilder-0.9.0/tests/prefab/shared → ducktools_classbuilder-0.10.0/tests/prefab}/test_init.py +121 -40
  30. ducktools_classbuilder-0.9.0/tests/prefab/dynamic/test_internals.py → ducktools_classbuilder-0.10.0/tests/prefab/test_internals_dict.py +1 -1
  31. {ducktools_classbuilder-0.9.0/tests/prefab/shared → ducktools_classbuilder-0.10.0/tests/prefab}/test_kw_only.py +51 -14
  32. ducktools_classbuilder-0.10.0/tests/prefab/test_replace.py +65 -0
  33. {ducktools_classbuilder-0.9.0/tests/prefab/shared → ducktools_classbuilder-0.10.0/tests/prefab}/test_repr.py +48 -14
  34. {ducktools_classbuilder-0.9.0/tests/prefab/dynamic → ducktools_classbuilder-0.10.0/tests/prefab}/test_slotted_class.py +11 -2
  35. {ducktools_classbuilder-0.9.0/tests/prefab/dynamic → ducktools_classbuilder-0.10.0/tests/prefab}/test_subclass_implementation.py +7 -2
  36. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/tests/test_core.py +14 -0
  37. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/tests/test_field_flags.py +6 -0
  38. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/tests/test_slotmakermeta.py +31 -18
  39. ducktools_classbuilder-0.10.0/uv.lock +910 -0
  40. ducktools_classbuilder-0.9.0/src/ducktools/classbuilder/_version.py +0 -2
  41. ducktools_classbuilder-0.9.0/src/ducktools_classbuilder.egg-info/requires.txt +0 -17
  42. ducktools_classbuilder-0.9.0/tests/conftest.py +0 -10
  43. ducktools_classbuilder-0.9.0/tests/prefab/shared/conftest.py +0 -17
  44. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/creation.py +0 -144
  45. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/creation_empty.py +0 -17
  46. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/dunders.py +0 -66
  47. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/fails/creation_2.py +0 -7
  48. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/fails/creation_3.py +0 -7
  49. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/fails/creation_5.py +0 -6
  50. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/fails/inheritance_1.py +0 -11
  51. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/fails/inheritance_2.py +0 -12
  52. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/funcs_prefabs.py +0 -20
  53. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/hint_syntax.py +0 -19
  54. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/inheritance.py +0 -65
  55. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/init_ex.py +0 -117
  56. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/kw_only.py +0 -49
  57. ducktools_classbuilder-0.9.0/tests/prefab/shared/examples/repr_func.py +0 -45
  58. ducktools_classbuilder-0.9.0/tests/prefab/shared/test_creation.py +0 -237
  59. ducktools_classbuilder-0.9.0/tests/prefab/shared/test_dunders.py +0 -120
  60. ducktools_classbuilder-0.9.0/tests/prefab/shared/test_inheritance.py +0 -61
  61. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/.github/dependabot.yml +0 -0
  62. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/.gitignore +0 -0
  63. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/.readthedocs.yaml +0 -0
  64. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/LICENSE +0 -0
  65. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/MANIFEST.in +0 -0
  66. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/README.md +0 -0
  67. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs/Makefile +0 -0
  68. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs/api.md +0 -0
  69. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs/approach_vs_tool.md +0 -0
  70. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs/conf.py +0 -0
  71. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs/extension_examples.md +0 -0
  72. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs/generated_code.md +0 -0
  73. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs/index.md +0 -0
  74. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs/make.bat +0 -0
  75. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs/perf/performance_tests.md +0 -0
  76. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs/prefab/index.md +0 -0
  77. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs_code/docs_ex10_frozen_attributes.py +0 -0
  78. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs_code/docs_ex1_basic.py +0 -0
  79. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs_code/docs_ex2_register.py +0 -0
  80. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs_code/docs_ex3_iterable.py +0 -0
  81. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs_code/docs_ex5_frozen.py +0 -0
  82. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs_code/docs_ex7_posonly.py +0 -0
  83. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs_code/docs_ex8_converters.py +0 -0
  84. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/docs_code/index_example.py +0 -0
  85. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/setup.cfg +0 -0
  86. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/src/ducktools/classbuilder/annotations.pyi +0 -0
  87. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/src/ducktools/classbuilder/py.typed +0 -0
  88. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/src/ducktools_classbuilder.egg-info/dependency_links.txt +0 -0
  89. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/src/ducktools_classbuilder.egg-info/top_level.txt +0 -0
  90. {ducktools_classbuilder-0.9.0/tests/prefab/dynamic → ducktools_classbuilder-0.10.0/tests/prefab}/test_compare_attrib.py +0 -0
  91. {ducktools_classbuilder-0.9.0/tests/prefab/dynamic → ducktools_classbuilder-0.10.0/tests/prefab}/test_frozen.py +0 -0
  92. {ducktools_classbuilder-0.9.0/tests/prefab/dynamic → ducktools_classbuilder-0.10.0/tests/prefab}/test_pre_post_init.py +0 -0
  93. {ducktools_classbuilder-0.9.0/tests/prefab/dynamic → ducktools_classbuilder-0.10.0/tests/prefab}/test_private.py +0 -0
  94. {ducktools_classbuilder-0.9.0/tests/prefab/dynamic → ducktools_classbuilder-0.10.0/tests/prefab}/test_slots_novalues.py +0 -0
  95. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/tests/py312_tests/test_generic_annotations.py +0 -0
  96. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/tests/py314_tests/_test_support.py +0 -0
  97. {ducktools_classbuilder-0.9.0 → ducktools_classbuilder-0.10.0}/tests/py314_tests/test_forwardref_annotations.py +0 -0
@@ -14,7 +14,7 @@ jobs:
14
14
  fail-fast: false
15
15
  matrix:
16
16
  os: [ubuntu-latest]
17
- python-version: ["3.14-dev", "3.13", "3.12", "3.11", "3.10", "pypy-3.10", "3.9", "3.8"]
17
+ python-version: ["3.14-dev", "3.13", "3.12", "3.11", "pypy-3.11", "3.10"]
18
18
 
19
19
  steps:
20
20
  - uses: actions/checkout@v4
@@ -25,7 +25,7 @@ jobs:
25
25
  - name: Install dependencies
26
26
  run: |
27
27
  python -m pip install --upgrade pip
28
- python -m pip install -e .[testing]
28
+ python -m pip install -e . --group dev
29
29
  - name: Test with pytest
30
30
  run: |
31
31
  pytest tests/ --cov=src/ --cov-report=term-missing
@@ -35,14 +35,14 @@ jobs:
35
35
 
36
36
  steps:
37
37
  - uses: actions/checkout@v4
38
- - name: Set up Python 3.8
38
+ - name: Set up Python 3.10
39
39
  uses: actions/setup-python@v5
40
40
  with:
41
- python-version: "3.8"
41
+ python-version: "3.10"
42
42
  - name: Install dependencies
43
43
  run: |
44
44
  python -m pip install --upgrade pip
45
- python -m pip install -e .[testing,type_checking]
45
+ python -m pip install -e . --group dev
46
46
  - name: Check type stub files
47
47
  run: |
48
48
  python -m mypy.stubtest ducktools.classbuilder
@@ -14,7 +14,7 @@ jobs:
14
14
  - name: Set up Python
15
15
  uses: actions/setup-python@v5
16
16
  with:
17
- python-version: "3.8"
17
+ python-version: "3.10"
18
18
  - name: Install pypa/build
19
19
  run: >-
20
20
  python3 -m
@@ -69,7 +69,7 @@ jobs:
69
69
  name: python-package-distributions
70
70
  path: dist/
71
71
  - name: Sign the dists with Sigstore
72
- uses: sigstore/gh-action-sigstore-python@v3.0.0
72
+ uses: sigstore/gh-action-sigstore-python@v3.0.1
73
73
  with:
74
74
  release-signing-artifacts: false
75
75
  inputs: >-
@@ -15,7 +15,7 @@ jobs:
15
15
  - name: Set up Python
16
16
  uses: actions/setup-python@v5
17
17
  with:
18
- python-version: "3.8"
18
+ python-version: "3.10"
19
19
  - name: Install pypa/build
20
20
  run: >-
21
21
  python3 -m
@@ -52,4 +52,4 @@ jobs:
52
52
  - name: Publish distribution 📦 to TestPyPI
53
53
  uses: pypa/gh-action-pypi-publish@release/v1
54
54
  with:
55
- repository-url: https://test.pypi.org/legacy/
55
+ repository-url: https://test.pypi.org/legacy/
@@ -1,34 +1,25 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: ducktools-classbuilder
3
- Version: 0.9.0
3
+ Version: 0.10.0
4
4
  Summary: Toolkit for creating class boilerplate generators
5
5
  Author: David C Ellis
6
6
  Project-URL: Homepage, https://github.com/davidcellis/ducktools-classbuilder
7
7
  Classifier: Development Status :: 4 - Beta
8
- Classifier: Programming Language :: Python :: 3.8
9
- Classifier: Programming Language :: Python :: 3.9
10
8
  Classifier: Programming Language :: Python :: 3.10
11
9
  Classifier: Programming Language :: Python :: 3.11
12
10
  Classifier: Programming Language :: Python :: 3.12
13
11
  Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Programming Language :: Python :: 3.14
14
13
  Classifier: Operating System :: OS Independent
15
14
  Classifier: License :: OSI Approved :: MIT License
16
- Requires-Python: >=3.8
15
+ Requires-Python: >=3.10
17
16
  Description-Content-Type: text/markdown
18
17
  License-File: LICENSE
19
- Provides-Extra: testing
20
- Requires-Dist: pytest>=8.2; extra == "testing"
21
- Requires-Dist: pytest-cov; extra == "testing"
22
- Requires-Dist: typing_extensions; extra == "testing"
23
- Provides-Extra: type-checking
24
- Requires-Dist: mypy; extra == "type-checking"
25
- Provides-Extra: performance-tests
26
- Requires-Dist: attrs; extra == "performance-tests"
27
- Requires-Dist: pydantic; extra == "performance-tests"
28
18
  Provides-Extra: docs
29
- Requires-Dist: sphinx; extra == "docs"
30
- Requires-Dist: myst-parser; extra == "docs"
31
- Requires-Dist: sphinx_rtd_theme; extra == "docs"
19
+ Requires-Dist: sphinx>=8.1; extra == "docs"
20
+ Requires-Dist: myst-parser>=4.0; extra == "docs"
21
+ Requires-Dist: sphinx_rtd_theme>=3.0; extra == "docs"
22
+ Dynamic: license-file
32
23
 
33
24
  # Ducktools: Class Builder #
34
25
 
@@ -191,14 +191,13 @@ def reportclass(cls):
191
191
  slot_gatherer = dtbuild.make_slot_gatherer(CustomField)
192
192
 
193
193
 
194
- class ReportClass(metaclass=dtbuild.SlotMakerMeta):
194
+ class ReportClass(metaclass=dtbuild.SlotMakerMeta, gatherer=fields_attribute_gatherer):
195
195
  __slots__ = {}
196
- _meta_gatherer = fields_attribute_gatherer
197
-
196
+
198
197
  def __init_subclass__(cls):
199
- # Check if the metaclass has generated slots
200
- meta_slotted = '__slots__' in vars(cls) and isinstance(cls.__slots__, dtbuild.SlotFields)
201
- gatherer = slot_gatherer if meta_slotted else fields_attribute_gatherer
198
+ # Check if the metaclass has pre-gathered data
199
+ pre_gathered = dtbuild.GATHERED_DATA in vars(cls)
200
+ gatherer = dtbuild.pre_gathered_gatherer if pre_gathered else fields_attribute_gatherer
202
201
  methods = {
203
202
  dtbuild.eq_maker,
204
203
  dtbuild.repr_maker,
@@ -6,9 +6,10 @@ from ducktools.classbuilder import (
6
6
  default_methods,
7
7
  get_fields,
8
8
  get_methods,
9
- slot_gatherer,
9
+ pre_gathered_gatherer,
10
10
  Field,
11
11
  SlotMakerMeta,
12
+ GATHERED_DATA,
12
13
  NOTHING,
13
14
  )
14
15
 
@@ -110,16 +111,15 @@ def annotatedclass(cls=None, *, kw_only=False):
110
111
 
111
112
 
112
113
  # As a base class with slots
113
- class AnnotatedClass(metaclass=SlotMakerMeta):
114
- # This attribute tells the slotmaker to use this gatherer
115
- _meta_gatherer = annotated_gatherer
116
-
114
+ class AnnotatedClass(metaclass=SlotMakerMeta, gatherer=annotated_gatherer):
115
+
117
116
  def __init_subclass__(cls, kw_only=False, **kwargs):
117
+ pre_gathered = GATHERED_DATA in cls.__dict__
118
118
  slots = "__slots__" in cls.__dict__
119
119
 
120
120
  # if slots is True then fields will already be present in __slots__
121
121
  # Use the slot_gatherer for this case
122
- gatherer = slot_gatherer if slots else annotated_gatherer
122
+ gatherer = pre_gathered_gatherer if pre_gathered else annotated_gatherer
123
123
 
124
124
  builder(
125
125
  cls,
@@ -139,10 +139,10 @@ if __name__ == "__main__":
139
139
  class X:
140
140
  x: str
141
141
  y: ClassVar[str] = "This should be ignored"
142
- z: Annotated[ClassVar[str], "Should be ignored"] = "This should also be ignored"
143
- a: Annotated[int, NO_INIT] = "Not In __init__ signature"
142
+ z: Annotated[ClassVar[str], "Should be ignored"] = "This should also be ignored" # type: ignore
143
+ a: Annotated[int, NO_INIT] = "Not In __init__ signature" # type: ignore
144
144
  b: Annotated[str, NO_REPR] = "Not In Repr"
145
- c: Annotated[list[str], NO_COMPARE] = Field(default_factory=list)
145
+ c: Annotated[list[str], NO_COMPARE] = Field(default_factory=list) # type: ignore
146
146
  d: Annotated[str, IGNORE_ALL] = "Not Anywhere"
147
147
  e: Annotated[str, KW_ONLY, NO_COMPARE]
148
148
 
@@ -150,23 +150,23 @@ if __name__ == "__main__":
150
150
  class Y(AnnotatedClass):
151
151
  x: str
152
152
  y: ClassVar[str] = "This should be ignored"
153
- z: Annotated[ClassVar[str], "Should be ignored"] = "This should also be ignored"
154
- a: Annotated[int, NO_INIT] = "Not In __init__ signature"
153
+ z: Annotated[ClassVar[str], "Should be ignored"] = "This should also be ignored" # type: ignore
154
+ a: Annotated[int, NO_INIT] = "Not In __init__ signature" # type: ignore
155
155
  b: Annotated[str, NO_REPR] = "Not In Repr"
156
- c: Annotated[list[str], NO_COMPARE] = Field(default_factory=list)
156
+ c: Annotated[list[str], NO_COMPARE] = Field(default_factory=list) # type: ignore
157
157
  d: Annotated[str, IGNORE_ALL] = "Not Anywhere"
158
158
  e: Annotated[str, KW_ONLY, NO_COMPARE]
159
159
 
160
160
 
161
161
  # Unslotted Demo
162
- ex = X("Value of x", e="Value of e")
162
+ ex = X("Value of x", e="Value of e") # type: ignore
163
163
  print(ex, "\n")
164
164
 
165
165
  pp(get_fields(X))
166
166
  print("\n")
167
167
 
168
168
  # Slotted Demo
169
- ex = Y("Value of x", e="Value of e")
169
+ ex = Y("Value of x", e="Value of e") # type: ignore
170
170
  print(ex, "\n")
171
171
 
172
172
  print(f"Slots: {Y.__dict__.get('__slots__')}")
@@ -115,14 +115,13 @@ def reportclass(cls):
115
115
  slot_gatherer = dtbuild.make_slot_gatherer(CustomField)
116
116
 
117
117
 
118
- class ReportClass(metaclass=dtbuild.SlotMakerMeta):
118
+ class ReportClass(metaclass=dtbuild.SlotMakerMeta, gatherer=fields_attribute_gatherer):
119
119
  __slots__ = {}
120
- _meta_gatherer = fields_attribute_gatherer
121
-
120
+
122
121
  def __init_subclass__(cls):
123
- # Check if the metaclass has generated slots
124
- meta_slotted = '__slots__' in vars(cls) and isinstance(cls.__slots__, dtbuild.SlotFields)
125
- gatherer = slot_gatherer if meta_slotted else fields_attribute_gatherer
122
+ # Check if the metaclass has pre-gathered data
123
+ pre_gathered = dtbuild.GATHERED_DATA in vars(cls)
124
+ gatherer = dtbuild.pre_gathered_gatherer if pre_gathered else fields_attribute_gatherer
126
125
  methods = {
127
126
  dtbuild.eq_maker,
128
127
  dtbuild.repr_maker,
@@ -130,7 +129,6 @@ class ReportClass(metaclass=dtbuild.SlotMakerMeta):
130
129
  report_maker
131
130
  }
132
131
 
133
- # The class may still have slots unrelated to code generation
134
132
  slotted = "__slots__" in vars(cls)
135
133
  flags = {"slotted": slotted}
136
134
 
@@ -12,32 +12,47 @@ authors = [
12
12
  { name="David C Ellis" },
13
13
  ]
14
14
  readme="README.md"
15
- requires-python = ">=3.8"
15
+ requires-python = ">=3.10"
16
16
  classifiers = [
17
17
  "Development Status :: 4 - Beta",
18
- "Programming Language :: Python :: 3.8",
19
- "Programming Language :: Python :: 3.9",
20
18
  "Programming Language :: Python :: 3.10",
21
19
  "Programming Language :: Python :: 3.11",
22
20
  "Programming Language :: Python :: 3.12",
23
21
  "Programming Language :: Python :: 3.13",
22
+ "Programming Language :: Python :: 3.14",
24
23
  "Operating System :: OS Independent",
25
24
  "License :: OSI Approved :: MIT License",
26
25
  ]
27
26
  dynamic = ['version']
28
27
 
29
28
  [project.optional-dependencies]
30
- testing = ["pytest>=8.2", "pytest-cov", "typing_extensions"]
31
- type_checking = ["mypy"]
32
- performance_tests = ["attrs", "pydantic"]
33
- docs = ["sphinx", "myst-parser", "sphinx_rtd_theme"]
29
+ # Needed for the current readthedocs.yaml
30
+ docs = [
31
+ "sphinx>=8.1",
32
+ "myst-parser>=4.0",
33
+ "sphinx_rtd_theme>=3.0",
34
+ ]
35
+
36
+ [dependency-groups]
37
+ dev = [
38
+ "pytest>=8.4",
39
+ "pytest-cov>=6.1",
40
+ "mypy>=1.16",
41
+ ]
42
+ performance = [
43
+ "attrs>=25.0",
44
+ "pydantic>=2.11",
45
+ ]
34
46
 
35
47
  [tool.setuptools.packages.find]
36
48
  where = ["src"]
37
49
 
38
50
  [tool.setuptools_scm]
39
51
  version_file = "src/ducktools/classbuilder/_version.py"
40
- version_file_template = "__version__ = \"{version}\"\n__version_tuple__ = {version_tuple}\n"
52
+ version_file_template = """
53
+ __version__ = "{version}"
54
+ __version_tuple__ = {version_tuple}
55
+ """
41
56
 
42
57
  [project.urls]
43
58
  "Homepage" = "https://github.com/davidcellis/ducktools-classbuilder"
@@ -47,3 +62,8 @@ addopts= "--cov=src/ --cov-report=term-missing"
47
62
  testpaths = [
48
63
  "tests",
49
64
  ]
65
+
66
+ [tool.mypy]
67
+ # A combination of types in stubs and tests using dataclass syntax
68
+ # means that there are a number of annotations in otherwise unannotated areas
69
+ disable_error_code = ["annotation-unchecked"]