Builder API Autodocs
Slotclass example functions and classes
- class ducktools.classbuilder.Field(*, default=<NOTHING Sentinel>, default_factory=<NOTHING Sentinel>, type=<NOTHING Sentinel>, doc=None, init=True, repr=True, compare=True, kw_only=False)
A basic class to handle the assignment of defaults/factories with some metadata.
Intended to be extendable by subclasses for additional features.
Note: When run under pytest, Field instances are Frozen.
When subclassing, passing frozen=True will make your subclass frozen.
- Parameters:
default – Standard default value to be used for attributes with this field.
default_factory – A zero-argument function to be called to generate a default value, useful for mutable obects like lists.
type – The type of the attribute to be assigned by this field.
doc – The documentation for the attribute that appears when calling help(…) on the class. (Only in slotted classes).
init – Include in the class __init__ parameters.
repr – Include in the class __repr__.
compare – Include in the class __eq__.
kw_only – Make this a keyword only parameter in __init__.
- class ducktools.classbuilder.SlotFields
A plain dict subclass.
For declaring slotfields there are no additional features required other than recognising that this is intended to be used as a class generating dict and isn’t a regular dictionary that ended up in __slots__.
This should be replaced on __slots__ after fields have been gathered.
- ducktools.classbuilder.slotclass(cls=None, /, *, methods=frozenset({<MethodMaker for '__eq__' method>, <MethodMaker for '__init__' method>, <MethodMaker for '__repr__' method>}), syntax_check=True)
Example of class builder in action using __slots__ to find fields.
- Parameters:
cls – Class to be analysed and modified
methods – MethodMakers to be added to the class
syntax_check – check there are no arguments without defaults after arguments with defaults.
- Returns:
Modified class
Builder functions and classes
- ducktools.classbuilder.builder(cls=None, /, *, gatherer, methods, flags=None, fix_signature=True, field_getter=<function get_fields>)
The main builder for class generation
If the GATHERED_DATA attribute exists on the class it will be used instead of the provided gatherer.
- Parameters:
cls – Class to be analysed and have methods generated
gatherer (Callable[[type], tuple[dict[str, Field], dict[str, Any]]]) – Function to gather field information
methods (set[MethodMaker]) – MethodMakers to add to the class
flags (None | dict[str, bool]) – additional flags to store in the internals dictionary for use by method generators.
fix_signature (bool) – Add a __signature__ attribute to work-around an issue with inspect.signature incorrectly handling __init__ descriptors.
field_getter (Callable[[type], dict[str, Field]]) – function to use to retrieve fields from parent classes
- Returns:
The modified class (the class itself is modified, but this is expected).
- ducktools.classbuilder.make_unified_gatherer(field_type=<class 'ducktools.classbuilder.Field'>, leave_default_values=False)
Create a gatherer that will work via first slots, then Field(…) class attributes and finally annotations if no unannotated Field(…) attributes are present.
- Parameters:
field_type – The field class to use for gathering
leave_default_values – leave default values in place
- Returns:
gatherer function
Internals retrieval functions
- ducktools.classbuilder.functions.build_completed(cls)
Utility function to determine if a class has completed the construction process.
- Parameters:
cls – class to check
- Returns:
True if built, False otherwise
- ducktools.classbuilder.functions.get_fields(cls, *, local=False)
Utility function to gather the fields dictionary from the class internals.
- Parameters:
cls – generated class
local – get only fields that were not inherited
- Returns:
dictionary of keys and Field attribute info
- ducktools.classbuilder.functions.get_flags(cls)
Utility function to gather the flags dictionary from the class internals.
- Parameters:
cls – generated class
- Returns:
dictionary of keys and flag values
- ducktools.classbuilder.functions.get_methods(cls)
Utility function to gather the set of methods from the class internals.
- Parameters:
cls – generated class
- Returns:
dict of generated methods attached to the class by name
- ducktools.classbuilder.functions.get_generated_code(cls)
Retrieve the source code, globals and annotations of all generated methods as they would be generated for a specific class.
- Parameters:
cls – generated class
- Returns:
dict of generated method names and the GeneratedCode objects for the class
- ducktools.classbuilder.functions.print_generated_code(cls)
Print out all of the generated source code that will be executed for this class
This function is useful when checking that your code generators are writing source code as expected.
- Parameters:
cls – generated class
Method Generating Tools
- class ducktools.classbuilder.methods.GeneratedCode(source_code, globs=None, annotations=None)
This class provides a return value for the generated output from source code generators.
- Parameters:
source_code – The source code to provide to
execto generate the methodglobs – A globals dictionary with any names needed within the function
annotations – Annotations dictionary for the function signature
- class ducktools.classbuilder.methods.MethodMaker(funcname, code_generator, cached_generator=None, decorator=None)
The descriptor class to place where methods should be generated. This delays the actual generation and exec until the method is needed.
This is used to convert a code generator that returns code and a globals dictionary into a descriptor to assign on a generated class.
- Parameters:
funcname – name of the generated function eg __init__
code_generator – code generator function to operate on a class.
cached_generator – a method generator that includes an internal cache
decorator – a decorator to apply directly to method after it has been created
Prefab Class and Attributes
- ducktools.classbuilder.prefab.prefab(cls=None, *, init=True, repr=True, eq=True, order=False, iter=False, match_args=True, kw_only=False, frozen=False, replace=True, dict_method=False, gatherer=<function make_unified_gatherer.<locals>.field_unified_gatherer>, ignore_annotations=False)
Generate boilerplate code for dunder methods in a class.
Use as a decorator.
- Parameters:
cls – Class to convert to a prefab
init – generates __init__ if true or __prefab_init__ if false
repr – generate __repr__
eq – generate __eq__
iter – generate __iter__
match_args – generate __match_args__
kw_only – make all attributes keyword only
frozen – Prevent attribute values from being changed once defined (This does not prevent the modification of mutable attributes such as lists)
replace – generate a __replace__ method
dict_method – Include an as_dict method for faster dictionary creation
ignore_annotations – Ignore type annotations when gathering fields, only look for slots or attribute(…) values
- Returns:
class with __ methods defined
- class ducktools.classbuilder.prefab.Prefab
- classmethod __init_subclass__(**kwargs)
Generate boilerplate code for dunder methods in a class.
Use as a base class, slotted by default
- Parameters:
init – generates __init__ if true or __prefab_init__ if false
repr – generate __repr__
eq – generate __eq__
iter – generate __iter__
match_args – generate __match_args__
kw_only – make all attributes keyword only
frozen – Prevent attribute values from being changed once defined (This does not prevent the modification of mutable attributes such as lists)
replace – generate a __replace__ method
dict_method – Include an as_dict method for faster dictionary creation
ignore_annotations – Ignore type annotations when gathering fields, only look for slots or attribute(…) values
slots – automatically generate slots for this class’s attributes
gatherer – A gatherer to use for collecting `Attribute`s
- ducktools.classbuilder.prefab.attribute(*, default=<NOTHING Sentinel>, default_factory=<NOTHING Sentinel>, init=True, repr=True, compare=True, iter=True, kw_only=False, serialize=True, exclude_field=False, private=False, doc=None, metadata=None, type=<NOTHING Sentinel>)
Helper function to get an object to define a prefab Attribute
- Parameters:
default – Default value for this attribute
default_factory – 0 argument callable to give a default value (for otherwise mutable defaults, eg: list)
init – Include this attribute in the __init__ parameters
repr – Include this attribute in the class __repr__
compare – Include this attribute in the class __eq__
iter – Include this attribute in the class __iter__ if generated
kw_only – Make this argument keyword only in init
serialize – Include this attribute in methods that serialize to dict
exclude_field – Shorthand for setting repr, compare, iter and serialize to False
private – Short for init, repr, compare, iter, serialize = False, must have default or factory
doc – Parameter documentation for slotted classes
metadata – Dictionary for additional non-construction metadata
type – Type of this attribute
- Returns:
Attribute generated with these parameters.
- ducktools.classbuilder.prefab.get_attributes(cls, *, local=False)
Copy of get_fields, typed to return Attribute instead of Field. This is used in the prefab methods.
- Parameters:
cls – class built with _make_prefab
- Returns:
dict[str, Attribute] of all gathered attributes
- ducktools.classbuilder.prefab.build_prefab(class_name, attributes, *, bases=(), class_dict=None, init=True, repr=True, eq=True, order=False, iter=False, match_args=True, kw_only=False, frozen=False, replace=True, dict_method=False, slots=False)
Dynamically construct a (dynamic) prefab.
- Parameters:
class_name – name of the resulting prefab class
attributes – list of (name, attribute()) pairs to assign to the class for construction
bases – Base classes to inherit from
class_dict – Other values to add to the class dictionary on creation This is the ‘dict’ parameter from ‘type’
init – generates __init__ if true or __prefab_init__ if false
repr – generate __repr__
eq – generate __eq__
iter – generate __iter__
match_args – generate __match_args__
kw_only – make all attributes keyword only
frozen – Prevent attribute values from being changed once defined (This does not prevent the modification of mutable attributes such as lists)
replace – generate a __replace__ method
dict_method – Include an as_dict method for faster dictionary creation
slots – Make the resulting class slotted
- Returns:
class with __ methods defined
- ducktools.classbuilder.prefab.is_prefab(o)
Identifier function, return True if an object is a prefab class or if it is an instance of a prefab class.
The check works by looking for a PREFAB_FIELDS attribute.
- Parameters:
o – object for comparison
- Returns:
True/False
- ducktools.classbuilder.prefab.is_prefab_instance(o)
Identifier function, return True if an object is an instance of a prefab class.
The check works by looking for a PREFAB_FIELDS attribute.
- Parameters:
o – object for comparison
- Returns:
True/False
- ducktools.classbuilder.prefab.as_dict(o)
Get the valid fields from a prefab respecting the serialize values of attributes
- Parameters:
o – instance of a prefab class
- Returns:
dictionary of {k: v} from fields
- ducktools.classbuilder.prefab.replace(obj, /, **changes)
Create a copy of a prefab instance with values provided to ‘changes’ replaced
- Parameters:
obj – built class
- Returns:
new built class instance with changes applied