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.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.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.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

class ducktools.classbuilder.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

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

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