ducktools-classbuilder 0.3.0__tar.gz → 0.5.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.
- {ducktools_classbuilder-0.3.0/src/ducktools_classbuilder.egg-info → ducktools_classbuilder-0.5.0}/PKG-INFO +38 -13
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/README.md +36 -12
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/docs/api.md +10 -1
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/docs/extension_examples.md +286 -289
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/docs/index.md +21 -0
- ducktools_classbuilder-0.5.0/docs/perf/performance_tests.md +66 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/pyproject.toml +1 -1
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/src/ducktools/classbuilder/__init__.py +298 -94
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/src/ducktools/classbuilder/__init__.pyi +54 -13
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/src/ducktools/classbuilder/prefab.py +48 -111
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/src/ducktools/classbuilder/prefab.pyi +10 -18
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0/src/ducktools_classbuilder.egg-info}/PKG-INFO +38 -13
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/src/ducktools_classbuilder.egg-info/SOURCES.txt +1 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/src/ducktools_classbuilder.egg-info/requires.txt +3 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/creation.py +22 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/test_creation.py +37 -16
- ducktools_classbuilder-0.5.0/tests/test_annotated.py +136 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/test_core.py +63 -6
- ducktools_classbuilder-0.3.0/docs/perf/performance_tests.md +0 -63
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/LICENSE.md +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/MANIFEST.in +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/docs/Makefile +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/docs/approach_vs_tool.md +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/docs/conf.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/docs/make.bat +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/docs/prefab/index.md +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/setup.cfg +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/src/ducktools/classbuilder/py.typed +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/src/ducktools_classbuilder.egg-info/dependency_links.txt +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/src/ducktools_classbuilder.egg-info/top_level.txt +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/dynamic/test_compare_attrib.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/dynamic/test_construction.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/dynamic/test_internals.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/dynamic/test_pre_post_init.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/dynamic/test_slots_novalues.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/dynamic/test_slotted_class.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/conftest.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/creation_empty.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/dunders.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/fails/creation_1.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/fails/creation_2.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/fails/creation_3.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/fails/creation_5.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/fails/inheritance_1.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/fails/inheritance_2.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/frozen_prefabs.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/funcs_prefabs.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/hint_syntax.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/inheritance.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/init_ex.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/kw_only.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/examples/repr_func.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/test_dunders.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/test_frozen.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/test_funcs.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/test_hint_syntax.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/test_inheritance.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/test_init.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/test_kw_only.py +0 -0
- {ducktools_classbuilder-0.3.0 → ducktools_classbuilder-0.5.0}/tests/prefab/shared/test_repr.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ducktools-classbuilder
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Toolkit for creating class boilerplate generators
|
|
5
5
|
Author: David C Ellis
|
|
6
6
|
License: MIT License
|
|
@@ -41,6 +41,7 @@ Provides-Extra: testing
|
|
|
41
41
|
Requires-Dist: pytest; extra == "testing"
|
|
42
42
|
Requires-Dist: pytest-cov; extra == "testing"
|
|
43
43
|
Requires-Dist: mypy; extra == "testing"
|
|
44
|
+
Requires-Dist: typing_extensions; python_version < "3.10" and extra == "testing"
|
|
44
45
|
Provides-Extra: docs
|
|
45
46
|
Requires-Dist: sphinx; extra == "docs"
|
|
46
47
|
Requires-Dist: myst-parser; extra == "docs"
|
|
@@ -68,11 +69,12 @@ Install from PyPI with:
|
|
|
68
69
|
In order to create a class decorator using `ducktools.classbuilder` there are
|
|
69
70
|
a few things you need to prepare.
|
|
70
71
|
|
|
71
|
-
1. A field gathering function to analyse the class and collect valid `Field`s
|
|
72
|
+
1. A field gathering function to analyse the class and collect valid `Field`s and provide
|
|
73
|
+
any modifications that need to be applied to the class attributes.
|
|
72
74
|
* An example `slot_gatherer` is included.
|
|
73
75
|
2. Code generators that can make use of the gathered `Field`s to create magic method
|
|
74
|
-
source code.
|
|
75
|
-
* Example `
|
|
76
|
+
source code. To be made into descriptors by `MethodMaker`.
|
|
77
|
+
* Example `init_generator`, `repr_generator` and `eq_generator` generators are included.
|
|
76
78
|
3. A function that calls the `builder` function to apply both of these steps.
|
|
77
79
|
|
|
78
80
|
A field gathering function needs to take the original class as an argument and
|
|
@@ -90,25 +92,26 @@ class[^1] where keyword arguments define the names and values for the fields.
|
|
|
90
92
|
|
|
91
93
|
Code generator functions need to be converted to descriptors before being used.
|
|
92
94
|
This is done using the provided `MethodMaker` descriptor class.
|
|
93
|
-
ex: `
|
|
95
|
+
ex: `init_maker = MethodMaker("__init__", init_generator)`.
|
|
94
96
|
|
|
95
97
|
These parts can then be used to make a basic class boilerplate generator by
|
|
96
98
|
providing them to the `builder` function.
|
|
97
99
|
|
|
98
100
|
```python
|
|
99
101
|
from ducktools.classbuilder import (
|
|
100
|
-
builder,
|
|
101
|
-
slot_gatherer,
|
|
102
|
-
|
|
102
|
+
builder,
|
|
103
|
+
slot_gatherer,
|
|
104
|
+
init_generator, eq_generator, repr_generator,
|
|
103
105
|
MethodMaker,
|
|
104
106
|
)
|
|
105
107
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
init_maker = MethodMaker("__init__", init_generator)
|
|
109
|
+
repr_maker = MethodMaker("__repr__", repr_generator)
|
|
110
|
+
eq_maker = MethodMaker("__eq__", eq_generator)
|
|
111
|
+
|
|
109
112
|
|
|
110
113
|
def slotclass(cls):
|
|
111
|
-
return builder(cls, gatherer=slot_gatherer, methods={
|
|
114
|
+
return builder(cls, gatherer=slot_gatherer, methods={init_maker, repr_maker, eq_maker})
|
|
112
115
|
```
|
|
113
116
|
|
|
114
117
|
## Slot Class Usage ##
|
|
@@ -121,7 +124,7 @@ a similar manner to the `@dataclass` decorator from `dataclasses`.
|
|
|
121
124
|
> be used directly. (The included version has some extra features).
|
|
122
125
|
|
|
123
126
|
```python
|
|
124
|
-
from ducktools.classbuilder import Field, SlotFields
|
|
127
|
+
from ducktools.classbuilder import Field, SlotFields, slotclass
|
|
125
128
|
|
|
126
129
|
@slotclass
|
|
127
130
|
class SlottedDC:
|
|
@@ -206,6 +209,25 @@ print(f"{DataCoords is class_register[DataCoords.__name__] = }")
|
|
|
206
209
|
print(f"{SlotCoords is class_register[SlotCoords.__name__] = }")
|
|
207
210
|
```
|
|
208
211
|
|
|
212
|
+
## Using annotations anyway ##
|
|
213
|
+
|
|
214
|
+
For those that really want to use type annotations a basic `annotation_gatherer`
|
|
215
|
+
function and `@annotationclass` decorator are also included. Slots are not generated
|
|
216
|
+
in this case.
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
from ducktools.classbuilder import annotationclass
|
|
220
|
+
|
|
221
|
+
@annotationclass
|
|
222
|
+
class AnnotatedDC:
|
|
223
|
+
the_answer: int = 42
|
|
224
|
+
the_question: str = "What do you get if you multiply six by nine?"
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
ex = AnnotatedDC()
|
|
228
|
+
print(ex)
|
|
229
|
+
```
|
|
230
|
+
|
|
209
231
|
## What features does this have? ##
|
|
210
232
|
|
|
211
233
|
Included as an example implementation, the `slotclass` generator supports
|
|
@@ -218,6 +240,9 @@ It will copy values provided as the `type` to `Field` into the
|
|
|
218
240
|
Values provided to `doc` will be placed in the final `__slots__`
|
|
219
241
|
field so they are present on the class if `help(...)` is called.
|
|
220
242
|
|
|
243
|
+
A fairly basic `annotations_gatherer` and `annotationclass` are also included
|
|
244
|
+
and can be used to generate classbuilders that rely on annotations.
|
|
245
|
+
|
|
221
246
|
If you want something with more features you can look at the `prefab.py`
|
|
222
247
|
implementation which provides a 'prebuilt' implementation.
|
|
223
248
|
|
|
@@ -20,11 +20,12 @@ Install from PyPI with:
|
|
|
20
20
|
In order to create a class decorator using `ducktools.classbuilder` there are
|
|
21
21
|
a few things you need to prepare.
|
|
22
22
|
|
|
23
|
-
1. A field gathering function to analyse the class and collect valid `Field`s
|
|
23
|
+
1. A field gathering function to analyse the class and collect valid `Field`s and provide
|
|
24
|
+
any modifications that need to be applied to the class attributes.
|
|
24
25
|
* An example `slot_gatherer` is included.
|
|
25
26
|
2. Code generators that can make use of the gathered `Field`s to create magic method
|
|
26
|
-
source code.
|
|
27
|
-
* Example `
|
|
27
|
+
source code. To be made into descriptors by `MethodMaker`.
|
|
28
|
+
* Example `init_generator`, `repr_generator` and `eq_generator` generators are included.
|
|
28
29
|
3. A function that calls the `builder` function to apply both of these steps.
|
|
29
30
|
|
|
30
31
|
A field gathering function needs to take the original class as an argument and
|
|
@@ -42,25 +43,26 @@ class[^1] where keyword arguments define the names and values for the fields.
|
|
|
42
43
|
|
|
43
44
|
Code generator functions need to be converted to descriptors before being used.
|
|
44
45
|
This is done using the provided `MethodMaker` descriptor class.
|
|
45
|
-
ex: `
|
|
46
|
+
ex: `init_maker = MethodMaker("__init__", init_generator)`.
|
|
46
47
|
|
|
47
48
|
These parts can then be used to make a basic class boilerplate generator by
|
|
48
49
|
providing them to the `builder` function.
|
|
49
50
|
|
|
50
51
|
```python
|
|
51
52
|
from ducktools.classbuilder import (
|
|
52
|
-
builder,
|
|
53
|
-
slot_gatherer,
|
|
54
|
-
|
|
53
|
+
builder,
|
|
54
|
+
slot_gatherer,
|
|
55
|
+
init_generator, eq_generator, repr_generator,
|
|
55
56
|
MethodMaker,
|
|
56
57
|
)
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
init_maker = MethodMaker("__init__", init_generator)
|
|
60
|
+
repr_maker = MethodMaker("__repr__", repr_generator)
|
|
61
|
+
eq_maker = MethodMaker("__eq__", eq_generator)
|
|
62
|
+
|
|
61
63
|
|
|
62
64
|
def slotclass(cls):
|
|
63
|
-
return builder(cls, gatherer=slot_gatherer, methods={
|
|
65
|
+
return builder(cls, gatherer=slot_gatherer, methods={init_maker, repr_maker, eq_maker})
|
|
64
66
|
```
|
|
65
67
|
|
|
66
68
|
## Slot Class Usage ##
|
|
@@ -73,7 +75,7 @@ a similar manner to the `@dataclass` decorator from `dataclasses`.
|
|
|
73
75
|
> be used directly. (The included version has some extra features).
|
|
74
76
|
|
|
75
77
|
```python
|
|
76
|
-
from ducktools.classbuilder import Field, SlotFields
|
|
78
|
+
from ducktools.classbuilder import Field, SlotFields, slotclass
|
|
77
79
|
|
|
78
80
|
@slotclass
|
|
79
81
|
class SlottedDC:
|
|
@@ -158,6 +160,25 @@ print(f"{DataCoords is class_register[DataCoords.__name__] = }")
|
|
|
158
160
|
print(f"{SlotCoords is class_register[SlotCoords.__name__] = }")
|
|
159
161
|
```
|
|
160
162
|
|
|
163
|
+
## Using annotations anyway ##
|
|
164
|
+
|
|
165
|
+
For those that really want to use type annotations a basic `annotation_gatherer`
|
|
166
|
+
function and `@annotationclass` decorator are also included. Slots are not generated
|
|
167
|
+
in this case.
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from ducktools.classbuilder import annotationclass
|
|
171
|
+
|
|
172
|
+
@annotationclass
|
|
173
|
+
class AnnotatedDC:
|
|
174
|
+
the_answer: int = 42
|
|
175
|
+
the_question: str = "What do you get if you multiply six by nine?"
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
ex = AnnotatedDC()
|
|
179
|
+
print(ex)
|
|
180
|
+
```
|
|
181
|
+
|
|
161
182
|
## What features does this have? ##
|
|
162
183
|
|
|
163
184
|
Included as an example implementation, the `slotclass` generator supports
|
|
@@ -170,6 +191,9 @@ It will copy values provided as the `type` to `Field` into the
|
|
|
170
191
|
Values provided to `doc` will be placed in the final `__slots__`
|
|
171
192
|
field so they are present on the class if `help(...)` is called.
|
|
172
193
|
|
|
194
|
+
A fairly basic `annotations_gatherer` and `annotationclass` are also included
|
|
195
|
+
and can be used to generate classbuilders that rely on annotations.
|
|
196
|
+
|
|
173
197
|
If you want something with more features you can look at the `prefab.py`
|
|
174
198
|
implementation which provides a 'prebuilt' implementation.
|
|
175
199
|
|
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
.. autofunction:: ducktools.classbuilder::slotclass
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
```{eval-rst}
|
|
18
|
+
.. autofunction:: ducktools.classbuilder::annotationclass
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
|
|
17
22
|
## Builder functions and classes ##
|
|
18
23
|
|
|
19
24
|
```{eval-rst}
|
|
@@ -33,7 +38,11 @@
|
|
|
33
38
|
```
|
|
34
39
|
|
|
35
40
|
```{eval-rst}
|
|
36
|
-
.. autofunction:: ducktools.classbuilder::
|
|
41
|
+
.. autofunction:: ducktools.classbuilder::make_slot_gatherer
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```{eval-rst}
|
|
45
|
+
.. autofunction:: ducktools.classbuilder::make_annotation_gatherer
|
|
37
46
|
```
|
|
38
47
|
|
|
39
48
|
```{eval-rst}
|