typed_descriptors.base

Abstract base class for descriptors backed by protected/private attributes.

DescriptorBase

class DescriptorBase(type, /, *, backed_by=None, use_dict=None, use_slots=None)[source]

Bases: TypedDescriptor[T]

Base class for descriptors backed by an attribute whose name and access mode is determined by the following logic.

Logic for using __dict__ vs “attr” functions for access to the backing attribute:

  1. If the use_dict argument is set to True in the descriptor constructor, then __dict__ will be used. If the library is certain that __dict__ is not available on instances of the descriptor owner class (cf. is_dict_available), then a TypeError is raised at the time when __set_name__ is called.

  2. If the use_slots argument is set to True in the descriptor constructor, then the “attr” functions getattr, setattr, delattr and hasattr will be used. If the library is certain that __dict__ is not available on instances of the descriptor owner class (cf. is_dict_available) and the backing attribute name is not present in the class slots (cf. class_slots), then a TypeError is raised at the time when __set_name__ is called.

  3. If neither use_dict nor use_slots__ is set to True in the descriptor constructor (the default case), then is_dict_available is called and the result is used to determine whether to use __dict__ or slots for the backing attribute. Further validation is then performed, as described in points 1 and 2 above.

Naming logic for the backing attribute:

  1. If the backed_by argument is specified in the descriptor constructor, the string passed to it is used as name for the backing attribute.

  2. Else, if using __dict__ for access to the backing attribute, then the backing attribute name coincides with the descriptor name.

  3. Else, the backing attribute name is obtained by prepending one or two underscores to the descriptor name (one if the descriptor name starts with underscore, two if it doesn’t).

If the backing attribute name starts with two underscores but does not end with two underscores, name-mangling is automatically performed.

abstract __get__(instance, _)[source]

If the descriptor is accessed on an instance, returns the value of the descriptor on the given instance.

If the descriptor is accessed on the owner class, i.e. if instance is None, returns the descriptor object.

Parameters:
Return type:

T | Self

__init__(type, /, *, backed_by=None, use_dict=None, use_slots=None)[source]

Creates a new descriptor with the given type.

Parameters:
  • type (Type[T] | Any) – the type of the descriptor.

  • backed_by (Optional[str]) – name for the backing attribute (optional, default name used if not specified).

  • use_dict (Optional[Literal[True]]) – if set to True, __dict__ will be used to store the the backing attribute.

  • use_dict – if set to True, __slots__ will be used to store the the backing attribute.

  • use_slots (Optional[Literal[True]])

Raises:

TypeError – if the type cannot be validated by the typing_validation library.

Return type:

None

final __set_name__(owner, name)[source]

Hook called when the descriptor is assigned to a class attribute. Responsible for:

  • Setting the owner and name of the descriptor

  • Setting the name of the backing attribute (incl. name-mangling)

  • Determining how to access the backing attribute.

See DescriptorBase class documentation for the logic behind the backing attribute’s name and access mode.

Raises:
  • TypeError – if the descriptor is assigned more than once

  • TypeError – if the owner class has __slots__ and the descriptor name appears in __slots__

  • TypeError – if the owner class has __slots__, __dict__ is not in __slots__, and the backing attribute name is not in __slots__.

Parameters:
Return type:

None

property is_assigned

Whether the descriptor has been assigned its owner and name.

Return type:

bool

property name

The name of the attribute.

Return type:

str

property owner

The class that owns the attribute.

Return type:

Type[Any]

property type

The type of the attribute.

Return type:

Union[Type[T], Any]

T

T = ~T

Invariant type variable for generic values.

T_co

T_co = +T_co

Invariant type variable for generic values.

TypedDescriptor

class TypedDescriptor(*args, **kwargs)[source]

Bases: Protocol[T_co]

Structural type for typed descriptors.

__descriptor_type__

Indicates the type (or type annotation, if a string) for the descriptor.

Return type:

Any

__get__(instance, _)[source]

If the descriptor is accessed on an instance, returns the value of the descriptor on the given instance.

If the descriptor is accessed on the owner class, i.e. if instance is None, returns the descriptor object itself.

Parameters:
Return type:

T_co | Self

__set_name__(owner, name)[source]

Hook called when the descriptor is assigned to a class attribute, usually responsible for setting the owner and name of the descriptor.

Parameters:
Return type:

None

class_slots

class_slots(cls)[source]

Returns a tuple consisting of all slots for the given class and all non-private slots for all classes in its MRO. Returns None if slots are not defined for the class.

Parameters:

cls (type)

Return type:

tuple[str, …] | None

is_dict_available

is_dict_available(cls)[source]

Checks whether instances of a descriptor owner class have __dict__ available on them.

Parameters:

cls (Any)

Return type:

bool

name_mangle

name_mangle(owner, attr_name)[source]

If the given attribute name is private and not dunder, return its name-mangled version for the given owner class.

Parameters:
Return type:

str

name_unmangle

name_unmangle(owner, attr_name)[source]

If the given attribute name is name-mangled for the given owner class, removes the name-mangling prefix.

Parameters:
Return type:

str