pyTooling.Decorators

Decorators controlling visibility of entities in a Python module.

Hint

See high-level help for explanations and usage examples.

See also

pyTooling.MetaClasses

→ The meta-class offering the same features as class options.

pyTooling.Attributes

→ Attributes, which mark an entity instead of modifying it.

Variables

Functions

  • export(): Register the given function or class as publicly accessible in a module.

  • notimplemented(): Mark a method as not implemented and replace the implementation with a new method raising a NotImplementedError.

  • InheritDocString(): Merge the doc-string from given base-class into the class or method this decorator is applied to.

Classes


Variables

pyTooling.Decorators.Param

A parameter specification for function or method

~Param
pyTooling.Decorators.RetType

Type variable for a return type

~RetType
pyTooling.Decorators.Func

Type specification for a function

typing.Callable[~Param, ~RetType]

alias of Callable[[Param], RetType]

pyTooling.Decorators.T

A type variable for a classes or functions.

~T

Functions

pyTooling.Decorators.export(entity)[source]

Register the given function or class as publicly accessible in a module.

Creates or updates the __all__ attribute in the module in which the decorated entity is defined to include the name of the decorated entity.

to_export.py

another_file.py

from pyTooling.Decorators import export

@export
def exported():
  pass

def not_exported():
  pass
from .to_export import *


# 'exported' will be listed in __all__
assert "exported"         in globals()

# 'not_exported' won't be listed in __all__
assert "not_exported" not in globals()
Parameters:

entity (TypeVar(T, bound= Union[type, FunctionType])) – The function or class to include in __all__.

Return type:

TypeVar(T, bound= Union[type, FunctionType])

Returns:

The unmodified function or class.

Raises:
  • AttributeError – If parameter entity has no __module__ member.

  • TypeError – If parameter entity is not a top-level entity in a module.

  • TypeError – If parameter entity has no __name__.

  • ValueError – If the decorated entity has no __module__ attribute, so it can’t be added to __all__.

pyTooling.Decorators.notimplemented(message)[source]

Mark a method as not implemented and replace the implementation with a new method raising a NotImplementedError.

The original method is stored in <method>.__wrapped__ and it’s doc-string is copied to the replacing method. In additional the field <method>.__notImplemented__ is added.

example.py

class Data:
  @notimplemented
  def method(self) -> bool:
    '''This method needs to be implemented'''
    return True
Parameters:

message (str) – Text of the NotImplementedError raised by the replacement method.

Return type:

Callable[..., Any]

Returns:

Decorator function that replaces the decorated method.

See also

@abstractmethod

→ Mark a method as abstract and raise a NotImplementedError when called.

@mustoverride

→ Mark a method as mustoverride (minimal implementation, but can be called).

pyTooling.Decorators.InheritDocString(baseClass, strategy=DocStringMergeStrategy.BaseLast, prefix='', interfix='\\n\\n', postfix='')[source]

Merge the doc-string from given base-class into the class or method this decorator is applied to.

The decorated entity keeps what is specific to it and inherits the rest, so a description doesn’t have to be repeated. Which parts are taken from which doc-string, and in which order they are arranged, is selected with strategy; by default the base-class’ doc-string is appended to the derived entity’s doc-string (BaseLast).

A derived entity without a doc-string of its own inherits the base-class’ doc-string unchanged - that is the plain copy this decorator started out as, and it needs no special strategy.

Both doc-strings are dedented with inspect.cleandoc() before they are combined. This matters for Python versions before 3.13, where the compiler does not strip a doc-string’s indentation: combining a tab-indented base-class doc-string with a space-indented derived doc-string would otherwise leave the first part indented relative to the second, which renders as a block quote.

The result is assembled as prefix + part + interfix + part ... + postfix. Parts that are empty - a missing doc-string, or a body the strategy asked for that doesn’t exist - are omitted together with their interfix. If nothing remains, the decorated entity’s doc-string is left unchanged.

example.py

from pyTooling.Decorators import InheritDocString, DocStringMergeStrategy

class Class1:
  def method(self):
    '''Method's doc-string.'''

class Class2(Class1):
  @InheritDocString(Class1)
  def method(self):
    super().method()

merging.py

@InheritDocString(
  Class1,
  DocStringMergeStrategy.BaseLastWithoutSummary,
  interfix="\n\n**Inherited:**\n\n"
)
class Class2(Class1):
  '''What is specific to Class2.'''
Parameters:
  • baseClass (type) – Base-class to copy the doc-string from to the class or method being decorated.

  • strategy (DocStringMergeStrategy) – Optional, which parts of both doc-strings are used and in which order they are arranged; defaults to BaseLast.

  • prefix (str) – Optional, text inserted in front of the merged doc-string; defaults to an empty string.

  • interfix (str) – Optional, text inserted between the parts; defaults to a blank line ("\n\n").

  • postfix (str) – Optional, text appended to the merged doc-string; defaults to an empty string.

Return type:

Callable[[Union[Callable[[ParamSpec(Param)], TypeVar(RetType)], type]], Union[Callable[[ParamSpec(Param)], TypeVar(RetType)], type]]

Returns:

Decorator function that merges the doc-string.

See also

DocStringMergeStrategy

→ Selects which parts of both doc-strings are merged, and in which order.


Classes

class pyTooling.Decorators.readonly[source]

Marks a property as read-only.

The doc-string is taken from the getter-method, like property does.

A plain property hands out <property>.setter and <property>.deleter, so a property declared as read-only could be made writable again further down the class body. Both methods therefore raise an AttributeError instead.

See also

property

A decorator to convert getter, setter and deleter methods into a property applying the descriptor protocol.

Inheritance

Inheritance diagram of readonly

fget: Callable[[Any], _ReturnType]

The getter-method; a read-only property is always constructed from one.

__init__(fget, doc=None)[source]

Create a read-only property from a getter-method.

property accepts a setter and a deleter here as well; this class does not, because it exists to reject them. Narrowing the signature to the getter is also what binds the type variable, so that reading the property hands out the getter’s return type instead of Any.

Parameters:
  • fget (Callable[[Any], TypeVar(_ReturnType)]) – The getter-method the property is constructed from.

  • doc (Optional[str]) – Optional, doc-string of the property. If None, the getter-method’s doc-string is used.

Return type:

None

getter(fget, /)[source]

Derive a read-only property with another getter-method from this one.

property implements this by reconstructing itself as type(self)(fget, fset, fdel, doc), which is the only reason a setter and a deleter would have to be accepted by __init__(). Constructing the property here instead keeps that signature down to what a read-only property actually has.

Parameters:

fget (Callable[[Any], TypeVar(_ReturnType)]) – The getter-method of the derived property.

Return type:

readonly[TypeVar(_ReturnType)]

Returns:

A new read-only property using the given getter-method, and its doc-string.

__get__(instance, owner=None, /)[source]

Return the value of the property, or the property itself when it is read from the class.

Overloads:
  • self, instance (None), owner (type) → readonly[_ReturnType]

  • self, instance (Any), owner (Nullable[type]) → _ReturnType

Parameters:
  • instance (Any)

  • owner (type | None)

Return type:

readonly[_ReturnType] | _ReturnType

Declaring this - property implements it already - is what tells a type checker that the value has the getter’s return type. Without it, every read of a @readonly property is Any, and that spreads: a comparison of two such values, or a method returning one, becomes Any as well.

Parameters:
  • instance (Any) – The object the property is read from, or None when it is read from the class.

  • owner (Optional[type]) – Optional, the class the property is defined in.

Returns:

The value the getter returns, or this property when read from the class.

Return type:

readonly[_ReturnType] | _ReturnType

setter(fset)[source]

Reject attaching a setter to a read-only property.

Parameters:

fset (Callable[..., Any]) – The setter-method that was to be attached.

Raises:

AttributeError – Always, because a read-only property can’t have a setter.
Use @property instead of @readonly, if the property should be writable.

Return type:

NoReturn

deleter(fdel)[source]

Reject attaching a deleter to a read-only property.

Parameters:

fdel (Callable[..., Any]) – The deleter-method that was to be attached.

Raises:

AttributeError – Always, because a read-only property can’t have a deleter.
Use @property instead of @readonly, if the property should be deletable.

Return type:

NoReturn

__delete__(instance, /)

Delete an attribute of instance.

__getattribute__(name, /)

Return getattr(self, name).

classmethod __new__(*args, **kwargs)
__set__(instance, value, /)

Set an attribute of instance to value.

__set_name__(owner, name, /)

Method to set name of a property.

class pyTooling.Decorators.DocStringMergeStrategy[source]

Strategy InheritDocString() follows when it combines the base-class’ and the derived entity’s doc-strings.

A doc-string’s summary is its first paragraph - the text up to the first blank line. Whatever follows is its body. A strategy naming WithoutSummary drops the summary of the doc-string it is applied to, because the other doc-string already provides one.

See also

@InheritDocString

→ Copy or merge a base-class’ doc-string into the derived entity.

Inheritance

Inheritance diagram of DocStringMergeStrategy

SummaryOnly = 0

The base-class’ summary, then the derived entity’s doc-string.

BaseLast = 1

The derived entity’s doc-string, then the base-class’ doc-string.

BaseLastWithoutSummary = 2

The derived entity’s doc-string, then the base-class’ body.

BaseFirst = 3

The base-class’ doc-string, then the derived entity’s doc-string.

classmethod __contains__(value)

Return True if value is in cls.

value is in cls if: 1) value is a member of cls, or 2) value is the value of one of the cls’s members. 3) value is a pseudo-member (flags)

classmethod __getitem__(name)

Return the member matching name.

classmethod __iter__()

Return members in definition order.

classmethod __len__()

Return the number of members (no aliases)

BaseInBetweenWithoutSummary = 4

The derived entity’s summary, the base-class’ body, then the derived body.