ducktools-classbuilder 0.1.0__tar.gz → 0.2.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 (59) hide show
  1. ducktools_classbuilder-0.2.0/MANIFEST.in +9 -0
  2. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/PKG-INFO +89 -23
  3. ducktools_classbuilder-0.2.0/README.md +197 -0
  4. ducktools_classbuilder-0.2.0/docs/Makefile +20 -0
  5. ducktools_classbuilder-0.2.0/docs/api.md +41 -0
  6. ducktools_classbuilder-0.2.0/docs/approach_vs_tool.md +16 -0
  7. ducktools_classbuilder-0.2.0/docs/conf.py +29 -0
  8. ducktools_classbuilder-0.2.0/docs/extension_examples.md +919 -0
  9. ducktools_classbuilder-0.2.0/docs/index.md +69 -0
  10. ducktools_classbuilder-0.2.0/docs/make.bat +35 -0
  11. ducktools_classbuilder-0.2.0/docs/perf/performance_tests.md +63 -0
  12. ducktools_classbuilder-0.2.0/docs/prefab/index.md +279 -0
  13. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/pyproject.toml +1 -1
  14. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/src/ducktools/classbuilder/__init__.py +35 -12
  15. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/src/ducktools/classbuilder/__init__.pyi +25 -22
  16. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/src/ducktools/classbuilder/prefab.py +46 -24
  17. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/src/ducktools/classbuilder/prefab.pyi +25 -13
  18. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/src/ducktools_classbuilder.egg-info/PKG-INFO +89 -23
  19. ducktools_classbuilder-0.2.0/src/ducktools_classbuilder.egg-info/SOURCES.txt +55 -0
  20. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/src/ducktools_classbuilder.egg-info/requires.txt +1 -0
  21. ducktools_classbuilder-0.2.0/tests/prefab/dynamic/test_compare_attrib.py +17 -0
  22. ducktools_classbuilder-0.2.0/tests/prefab/dynamic/test_construction.py +93 -0
  23. ducktools_classbuilder-0.2.0/tests/prefab/dynamic/test_internals.py +27 -0
  24. ducktools_classbuilder-0.2.0/tests/prefab/dynamic/test_pre_post_init.py +57 -0
  25. ducktools_classbuilder-0.2.0/tests/prefab/dynamic/test_slots_novalues.py +17 -0
  26. ducktools_classbuilder-0.2.0/tests/prefab/dynamic/test_slotted_class.py +107 -0
  27. ducktools_classbuilder-0.2.0/tests/prefab/shared/conftest.py +17 -0
  28. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/creation.py +122 -0
  29. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/creation_empty.py +17 -0
  30. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/dunders.py +66 -0
  31. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/fails/creation_1.py +6 -0
  32. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/fails/creation_2.py +7 -0
  33. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/fails/creation_3.py +7 -0
  34. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/fails/creation_5.py +6 -0
  35. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/fails/inheritance_1.py +11 -0
  36. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/fails/inheritance_2.py +12 -0
  37. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/frozen_prefabs.py +8 -0
  38. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/funcs_prefabs.py +20 -0
  39. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/hint_syntax.py +19 -0
  40. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/inheritance.py +65 -0
  41. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/init_ex.py +117 -0
  42. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/kw_only.py +49 -0
  43. ducktools_classbuilder-0.2.0/tests/prefab/shared/examples/repr_func.py +45 -0
  44. ducktools_classbuilder-0.2.0/tests/prefab/shared/test_creation.py +222 -0
  45. ducktools_classbuilder-0.2.0/tests/prefab/shared/test_dunders.py +120 -0
  46. ducktools_classbuilder-0.2.0/tests/prefab/shared/test_frozen.py +60 -0
  47. ducktools_classbuilder-0.2.0/tests/prefab/shared/test_funcs.py +97 -0
  48. ducktools_classbuilder-0.2.0/tests/prefab/shared/test_hint_syntax.py +21 -0
  49. ducktools_classbuilder-0.2.0/tests/prefab/shared/test_inheritance.py +61 -0
  50. ducktools_classbuilder-0.2.0/tests/prefab/shared/test_init.py +190 -0
  51. ducktools_classbuilder-0.2.0/tests/prefab/shared/test_kw_only.py +92 -0
  52. ducktools_classbuilder-0.2.0/tests/prefab/shared/test_repr.py +49 -0
  53. ducktools-classbuilder-0.1.0/README.md +0 -132
  54. ducktools-classbuilder-0.1.0/src/ducktools_classbuilder.egg-info/SOURCES.txt +0 -13
  55. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/LICENSE.md +0 -0
  56. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/setup.cfg +0 -0
  57. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/src/ducktools/classbuilder/py.typed +0 -0
  58. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/src/ducktools_classbuilder.egg-info/dependency_links.txt +0 -0
  59. {ducktools-classbuilder-0.1.0 → ducktools_classbuilder-0.2.0}/src/ducktools_classbuilder.egg-info/top_level.txt +0 -0
@@ -0,0 +1,9 @@
1
+ graft src
2
+ graft tests
3
+ graft docs
4
+
5
+ prune */build
6
+ prune */dist
7
+ prune */.pytest_cache
8
+
9
+ global-exclude *~ *.py[cod] *.so
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ducktools-classbuilder
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Toolkit for creating class boilerplate generators
5
5
  Author: David C Ellis
6
6
  License: MIT License
@@ -40,6 +40,7 @@ License-File: LICENSE.md
40
40
  Provides-Extra: testing
41
41
  Requires-Dist: pytest; extra == "testing"
42
42
  Requires-Dist: pytest-cov; extra == "testing"
43
+ Requires-Dist: mypy; extra == "testing"
43
44
  Provides-Extra: docs
44
45
  Requires-Dist: sphinx; extra == "docs"
45
46
  Requires-Dist: myst-parser; extra == "docs"
@@ -53,19 +54,74 @@ of writing... functions... that will bring back the **joy** of writing classes.
53
54
  Maybe.
54
55
 
55
56
  While `attrs` and `dataclasses` are class boilerplate generators,
56
- `ducktools.classbuilder` is intended to be a dataclasses-like generator.
57
+ `ducktools.classbuilder` is intended to be a `@dataclass`-like generator.
57
58
  The goal is to handle some of the basic functions and to allow for flexible
58
59
  customization of both the field collection and the method generation.
59
60
 
60
61
  `ducktools.classbuilder.prefab` includes a prebuilt implementation using these tools.
61
62
 
63
+ Install from PyPI with:
64
+ `python -m pip install ducktools-classbuilder`
65
+
66
+ ## Usage: building a class decorator ##
67
+
68
+ In order to create a class decorator using `ducktools.classbuilder` there are
69
+ a few things you need to prepare.
70
+
71
+ 1. A field gathering function to analyse the class and collect valid `Field`s.
72
+ * An example `slot_gatherer` is included.
73
+ 2. Code generators that can make use of the gathered `Field`s to create magic method
74
+ source code.
75
+ * Example `init_maker`, `repr_maker` and `eq_maker` generators are included.
76
+ 3. A function that calls the `builder` function to apply both of these steps.
77
+
78
+ A field gathering function needs to take the original class as an argument and
79
+ return a dictionary of `{key: Field(...)}` pairs.
80
+
81
+ > [!NOTE]
82
+ > The `builder` will handle inheritance so do not collect fields from parent classes.
83
+
84
+ The code generators take the class as the only argument and return a tuple
85
+ of method source code and globals to be provided to `exec(code, globs)` in order
86
+ to generate the actual method.
87
+
88
+ The provided `slot_gatherer` looks for `__slots__` being assigned a `SlotFields`
89
+ class[^1] where keyword arguments define the names and values for the fields.
90
+
91
+ Code generator functions need to be converted to descriptors before being used.
92
+ This is done using the provided `MethodMaker` descriptor class.
93
+ ex: `init_desc = MethodMaker("__init__", init_maker)`
94
+
95
+ These parts can then be used to make a basic class boilerplate generator by
96
+ providing them to the `builder` function.
97
+
98
+ ```python
99
+ from ducktools.classbuilder import (
100
+ builder,
101
+ slot_gatherer,
102
+ init_maker, eq_maker, repr_maker,
103
+ MethodMaker,
104
+ )
105
+
106
+ init_desc = MethodMaker("__init__", init_maker)
107
+ repr_desc = MethodMaker("__repr__", repr_maker)
108
+ eq_desc = MethodMaker("__eq__", eq_maker)
109
+
110
+ def slotclass(cls):
111
+ return builder(cls, gatherer=slot_gatherer, methods={init_desc, repr_desc, eq_desc})
112
+ ```
113
+
62
114
  ## Slot Class Usage ##
63
115
 
64
- The building toolkit also includes a basic implementation that uses
65
- `__slots__` to define the fields by assigning a `SlotFields` instance.
116
+ This created `slotclass` function can then be used as a decorator to generate classes in
117
+ a similar manner to the `@dataclass` decorator from `dataclasses`.
118
+
119
+ > [!NOTE]
120
+ > `ducktools.classbuilder` includes a premade version of `slotclass` that can
121
+ > be used directly. (The included version has some extra features).
66
122
 
67
123
  ```python
68
- from ducktools.classbuilder import slotclass, Field, SlotFields
124
+ from ducktools.classbuilder import Field, SlotFields
69
125
 
70
126
  @slotclass
71
127
  class SlottedDC:
@@ -81,28 +137,36 @@ ex = SlottedDC()
81
137
  print(ex)
82
138
  ```
83
139
 
84
- ## Why does the basic implementation use slots? ##
140
+ > [!TIP]
141
+ > For more information and examples of creating class generators with additional
142
+ > features using the builder see
143
+ > [the docs](https://ducktools-classbuilder.readthedocs.io/en/latest/extension_examples.html)
144
+
145
+ ## Why does your example use `__slots__` instead of annotations? ##
85
146
 
86
- Dataclasses has a problem when you use `@dataclass(slots=True)`,
87
- although this is not unique to dataclasses but inherent to the way both
88
- `__slots__` and decorators work.
147
+ If you want to use `__slots__` in order to save memory you have to declare
148
+ them when the class is originally created as you can't add them later.
89
149
 
90
- In order for this to *appear* to work, dataclasses has to make a new class
91
- and attempt to copy over everything from the original. This is because
92
- decorators operate on classes *after they have been created* while slots
93
- need to be declared beforehand. While you can change the value of `__slots__`
94
- after a class has been created, this will have no effect on the internal
95
- structure of the class.
150
+ When you use `@dataclass(slots=True)`[^2] with `dataclasses` in order for
151
+ this to work, `dataclasses` has to make a new class and attempt to
152
+ copy over everything from the original.
153
+ This is because decorators operate on classes *after they have been created*
154
+ while slots need to be declared beforehand.
155
+ While you can change the value of `__slots__` after a class has been created,
156
+ this will have no effect on the internal structure of the class.
96
157
 
97
158
  By declaring the class using `__slots__` on the other hand, we can take
98
159
  advantage of the fact that it accepts a mapping, where the keys will be
99
160
  used as the attributes to create as slots. The values can then be used as
100
- the default values equivalently to how type hints are used in dataclasses.
161
+ the default values equivalently to how type hints are used in `dataclasses`.
101
162
 
102
- For example these two classes would be roughly equivalent, except
163
+ For example these two classes would be roughly equivalent, except that
103
164
  `@dataclass` has had to recreate the class from scratch while `@slotclass`
104
- has simply added the methods on to the original class. This is easy to
105
- demonstrate using another decorator.
165
+ has added the methods on to the original class.
166
+ This means that any references stored to the original class *before*
167
+ `@dataclass` has rebuilt the class will not be pointing towards the
168
+ correct class.
169
+ This can be demonstrated using a simple class register decorator.
106
170
 
107
171
  > This example requires Python 3.10 as earlier versions of
108
172
  > `dataclasses` did not support the `slots` argument.
@@ -140,7 +204,6 @@ print(SlotCoords())
140
204
 
141
205
  print(f"{DataCoords is class_register[DataCoords.__name__] = }")
142
206
  print(f"{SlotCoords is class_register[SlotCoords.__name__] = }")
143
-
144
207
  ```
145
208
 
146
209
  ## What features does this have? ##
@@ -158,9 +221,6 @@ field so they are present on the class if `help(...)` is called.
158
221
  If you want something with more features you can look at the `prefab.py`
159
222
  implementation which provides a 'prebuilt' implementation.
160
223
 
161
- For more information on creating class generators using the builder
162
- see [the docs](https://ducktools-classbuilder.readthedocs.io/en/latest/extension_examples.html)
163
-
164
224
  ## Will you add \<feature\> to `classbuilder.prefab`? ##
165
225
 
166
226
  No. Not unless it's something I need or find interesting.
@@ -177,3 +237,9 @@ with a specific feature, you can create or add it yourself.
177
237
  ## Credit ##
178
238
 
179
239
  Heavily inspired by [David Beazley's Cluegen](https://github.com/dabeaz/cluegen)
240
+
241
+ [^1]: `SlotFields` is actually just a subclassed `dict` with no changes. `__slots__`
242
+ works with dictionaries using the values of the keys, while fields are normally
243
+ used for documentation.
244
+
245
+ [^2]: or `@attrs.define`.
@@ -0,0 +1,197 @@
1
+ # Ducktools: Class Builder #
2
+
3
+ `ducktools-classbuilder` is *the* Python package that will bring you the **joy**
4
+ of writing... functions... that will bring back the **joy** of writing classes.
5
+
6
+ Maybe.
7
+
8
+ While `attrs` and `dataclasses` are class boilerplate generators,
9
+ `ducktools.classbuilder` is intended to be a `@dataclass`-like generator.
10
+ The goal is to handle some of the basic functions and to allow for flexible
11
+ customization of both the field collection and the method generation.
12
+
13
+ `ducktools.classbuilder.prefab` includes a prebuilt implementation using these tools.
14
+
15
+ Install from PyPI with:
16
+ `python -m pip install ducktools-classbuilder`
17
+
18
+ ## Usage: building a class decorator ##
19
+
20
+ In order to create a class decorator using `ducktools.classbuilder` there are
21
+ a few things you need to prepare.
22
+
23
+ 1. A field gathering function to analyse the class and collect valid `Field`s.
24
+ * An example `slot_gatherer` is included.
25
+ 2. Code generators that can make use of the gathered `Field`s to create magic method
26
+ source code.
27
+ * Example `init_maker`, `repr_maker` and `eq_maker` generators are included.
28
+ 3. A function that calls the `builder` function to apply both of these steps.
29
+
30
+ A field gathering function needs to take the original class as an argument and
31
+ return a dictionary of `{key: Field(...)}` pairs.
32
+
33
+ > [!NOTE]
34
+ > The `builder` will handle inheritance so do not collect fields from parent classes.
35
+
36
+ The code generators take the class as the only argument and return a tuple
37
+ of method source code and globals to be provided to `exec(code, globs)` in order
38
+ to generate the actual method.
39
+
40
+ The provided `slot_gatherer` looks for `__slots__` being assigned a `SlotFields`
41
+ class[^1] where keyword arguments define the names and values for the fields.
42
+
43
+ Code generator functions need to be converted to descriptors before being used.
44
+ This is done using the provided `MethodMaker` descriptor class.
45
+ ex: `init_desc = MethodMaker("__init__", init_maker)`
46
+
47
+ These parts can then be used to make a basic class boilerplate generator by
48
+ providing them to the `builder` function.
49
+
50
+ ```python
51
+ from ducktools.classbuilder import (
52
+ builder,
53
+ slot_gatherer,
54
+ init_maker, eq_maker, repr_maker,
55
+ MethodMaker,
56
+ )
57
+
58
+ init_desc = MethodMaker("__init__", init_maker)
59
+ repr_desc = MethodMaker("__repr__", repr_maker)
60
+ eq_desc = MethodMaker("__eq__", eq_maker)
61
+
62
+ def slotclass(cls):
63
+ return builder(cls, gatherer=slot_gatherer, methods={init_desc, repr_desc, eq_desc})
64
+ ```
65
+
66
+ ## Slot Class Usage ##
67
+
68
+ This created `slotclass` function can then be used as a decorator to generate classes in
69
+ a similar manner to the `@dataclass` decorator from `dataclasses`.
70
+
71
+ > [!NOTE]
72
+ > `ducktools.classbuilder` includes a premade version of `slotclass` that can
73
+ > be used directly. (The included version has some extra features).
74
+
75
+ ```python
76
+ from ducktools.classbuilder import Field, SlotFields
77
+
78
+ @slotclass
79
+ class SlottedDC:
80
+ __slots__ = SlotFields(
81
+ the_answer=42,
82
+ the_question=Field(
83
+ default="What do you get if you multiply six by nine?",
84
+ doc="Life, the Universe, and Everything",
85
+ ),
86
+ )
87
+
88
+ ex = SlottedDC()
89
+ print(ex)
90
+ ```
91
+
92
+ > [!TIP]
93
+ > For more information and examples of creating class generators with additional
94
+ > features using the builder see
95
+ > [the docs](https://ducktools-classbuilder.readthedocs.io/en/latest/extension_examples.html)
96
+
97
+ ## Why does your example use `__slots__` instead of annotations? ##
98
+
99
+ If you want to use `__slots__` in order to save memory you have to declare
100
+ them when the class is originally created as you can't add them later.
101
+
102
+ When you use `@dataclass(slots=True)`[^2] with `dataclasses` in order for
103
+ this to work, `dataclasses` has to make a new class and attempt to
104
+ copy over everything from the original.
105
+ This is because decorators operate on classes *after they have been created*
106
+ while slots need to be declared beforehand.
107
+ While you can change the value of `__slots__` after a class has been created,
108
+ this will have no effect on the internal structure of the class.
109
+
110
+ By declaring the class using `__slots__` on the other hand, we can take
111
+ advantage of the fact that it accepts a mapping, where the keys will be
112
+ used as the attributes to create as slots. The values can then be used as
113
+ the default values equivalently to how type hints are used in `dataclasses`.
114
+
115
+ For example these two classes would be roughly equivalent, except that
116
+ `@dataclass` has had to recreate the class from scratch while `@slotclass`
117
+ has added the methods on to the original class.
118
+ This means that any references stored to the original class *before*
119
+ `@dataclass` has rebuilt the class will not be pointing towards the
120
+ correct class.
121
+ This can be demonstrated using a simple class register decorator.
122
+
123
+ > This example requires Python 3.10 as earlier versions of
124
+ > `dataclasses` did not support the `slots` argument.
125
+
126
+ ```python
127
+ from dataclasses import dataclass
128
+ from ducktools.classbuilder import slotclass, SlotFields
129
+
130
+ class_register = {}
131
+
132
+
133
+ def register(cls):
134
+ class_register[cls.__name__] = cls
135
+ return cls
136
+
137
+
138
+ @dataclass(slots=True)
139
+ @register
140
+ class DataCoords:
141
+ x: float = 0.0
142
+ y: float = 0.0
143
+
144
+
145
+ @slotclass
146
+ @register
147
+ class SlotCoords:
148
+ __slots__ = SlotFields(x=0.0, y=0.0)
149
+ # Type hints don't affect class construction, these are optional.
150
+ x: float
151
+ y: float
152
+
153
+
154
+ print(DataCoords())
155
+ print(SlotCoords())
156
+
157
+ print(f"{DataCoords is class_register[DataCoords.__name__] = }")
158
+ print(f"{SlotCoords is class_register[SlotCoords.__name__] = }")
159
+ ```
160
+
161
+ ## What features does this have? ##
162
+
163
+ Included as an example implementation, the `slotclass` generator supports
164
+ `default_factory` for creating mutable defaults like lists, dicts etc.
165
+ It also supports default values that are not builtins (try this on
166
+ [Cluegen](https://github.com/dabeaz/cluegen)).
167
+
168
+ It will copy values provided as the `type` to `Field` into the
169
+ `__annotations__` dictionary of the class.
170
+ Values provided to `doc` will be placed in the final `__slots__`
171
+ field so they are present on the class if `help(...)` is called.
172
+
173
+ If you want something with more features you can look at the `prefab.py`
174
+ implementation which provides a 'prebuilt' implementation.
175
+
176
+ ## Will you add \<feature\> to `classbuilder.prefab`? ##
177
+
178
+ No. Not unless it's something I need or find interesting.
179
+
180
+ The original version of `prefab_classes` was intended to have every feature
181
+ anybody could possibly require, but this is no longer the case with this
182
+ rebuilt version.
183
+
184
+ I will fix bugs (assuming they're not actually intended behaviour).
185
+
186
+ However the whole goal of this module is if you want to have a class generator
187
+ with a specific feature, you can create or add it yourself.
188
+
189
+ ## Credit ##
190
+
191
+ Heavily inspired by [David Beazley's Cluegen](https://github.com/dabeaz/cluegen)
192
+
193
+ [^1]: `SlotFields` is actually just a subclassed `dict` with no changes. `__slots__`
194
+ works with dictionaries using the values of the keys, while fields are normally
195
+ used for documentation.
196
+
197
+ [^2]: or `@attrs.define`.
@@ -0,0 +1,20 @@
1
+ # Minimal makefile for Sphinx documentation
2
+ #
3
+
4
+ # You can set these variables from the command line, and also
5
+ # from the environment for the first two.
6
+ SPHINXOPTS ?=
7
+ SPHINXBUILD ?= sphinx-build
8
+ SOURCEDIR = .
9
+ BUILDDIR = _build
10
+
11
+ # Put it first so that "make" without argument is like "make help".
12
+ help:
13
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14
+
15
+ .PHONY: help Makefile
16
+
17
+ # Catch-all target: route all unknown targets to Sphinx using the new
18
+ # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19
+ %: Makefile
20
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@@ -0,0 +1,41 @@
1
+ # Builder API Autodocs #
2
+
3
+ ## Slotclass example functions and classes ##
4
+
5
+ ```{eval-rst}
6
+ .. autoclass:: ducktools.classbuilder::Field
7
+ ```
8
+
9
+ ```{eval-rst}
10
+ .. autoclass:: ducktools.classbuilder::SlotFields
11
+ ```
12
+
13
+ ```{eval-rst}
14
+ .. autofunction:: ducktools.classbuilder::slotclass
15
+ ```
16
+
17
+ ## Builder functions and classes ##
18
+
19
+ ```{eval-rst}
20
+ .. autofunction:: ducktools.classbuilder::builder
21
+ ```
22
+
23
+ ```{eval-rst}
24
+ .. autofunction:: ducktools.classbuilder::get_fields
25
+ ```
26
+
27
+ ```{eval-rst}
28
+ .. autofunction:: ducktools.classbuilder::get_flags
29
+ ```
30
+
31
+ ```{eval-rst}
32
+ .. autoclass:: ducktools.classbuilder::MethodMaker
33
+ ```
34
+
35
+ ```{eval-rst}
36
+ .. autofunction:: ducktools.classbuilder::slot_gatherer
37
+ ```
38
+
39
+ ```{eval-rst}
40
+ .. autofunction:: ducktools.classbuilder::fieldclass
41
+ ```
@@ -0,0 +1,16 @@
1
+ # Approaches and tools #
2
+
3
+ As this module's code generation is inspired by the workings of [David Beazley's Cluegen](https://github.com/dabeaz/cluegen)
4
+ I thought it was briefly worth discussing his note on learning an approach vs using a tool.
5
+
6
+ I think that learning an approach is valuable, this module would not exist without the
7
+ example given by `cluegen`. It also wouldn't exist if I hadn't needed to extend `cluegen`
8
+ for some basic features (try using `Path` default values with `cluegen`).
9
+
10
+ In the general spirit though, this module intends to provide some basic tools to help
11
+ build your own custom class generators.
12
+ The generator included in the base module is intended to be used to help 'bootstrap' a
13
+ modified generator with features that work how **you** want them to work.
14
+
15
+ The `prefab` module is the more fully featured powertool *I* built with these tools.
16
+ However, much like a prefabricated building, it may not be what you desire.
@@ -0,0 +1,29 @@
1
+ # Configuration file for the Sphinx documentation builder.
2
+ #
3
+ # For the full list of built-in configuration values, see the documentation:
4
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html
5
+
6
+ # -- Project information -----------------------------------------------------
7
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
8
+
9
+ project = 'ducktools-classbuilder'
10
+ copyright = '2024, David C Ellis'
11
+ author = 'David C Ellis'
12
+
13
+ # -- General configuration ---------------------------------------------------
14
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
15
+
16
+ extensions = ["myst_parser", "sphinx.ext.autodoc", "sphinx_rtd_theme"]
17
+
18
+ autodoc_typehints = "description"
19
+
20
+ templates_path = ['_templates']
21
+ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
22
+
23
+ autoclass_content = "both"
24
+
25
+ # -- Options for HTML output -------------------------------------------------
26
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
27
+
28
+ html_theme = 'sphinx_rtd_theme'
29
+ html_static_path = ['_static']