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 exec to generate the method

  • globs – 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