cottax.core.frozen.answer module

How a feature’s class gets into a consumer: 1. An Answer: one per class per interface, registered with @answers and found along the

class’s ancestry.

  1. A Choice: several fit, so a study names one; each final is marked @choice(interface), which registers nothing.

class Answer[source]

Bases: Frozen

The one right answer per node or place class. A level directly under Answer is a consumer’s interface, saying what it is answered per (about); the owner of a class it is about writes a final and registers it with @answers(*classes): a feature for its own, a consumer for its own and for core’s. A final holds no field: the registry builds it, cls().

about: AbstractClassVar[Any]

a class, a type alias of one, a protocol, or a tuple of those. @answers refuses a class that is none; a protocol is met by shape, which a class cannot be asked.

Type:

What the interface is answered per, bound by the interface

checks_answer: PerLevel[tuple[Callable[[Any, tuple[Any, ...]], Iterable[Violation]], ...]] = ()

why answer is refused beside the answers already registered for its interface (a word two would share).

Type:

check(answer, registered)

class Choice[source]

Bases: ABC

Several fit, so none is registered: a study names one in a slot, which the interface class’s docstring states in a Handed in as: block, an example of the call. Never an Answer as well.

answers[A: type[Answer]](*classes: type)[source]

Register an Answer final for each of classes. A class is answered once per interface: a second answer is refused, so nothing depends on import order, unless it has the first’s module and qualified name (a module reloaded), when it replaces it.

Return type:

Callable[[A], A]

answer[A: Answer](interface: type[A], obj: object, default: Any = _REFUSE)[source]

The interface answer registered for the class of obj (answer_for_class).

Return type:

A

answer_for_class[A: Answer](interface: type[A], cls: type, default: Any = _REFUSE)[source]

The interface answer registered for cls, looked up along its ancestry, most specific first. With none: default, or else refused.

Return type:

A

answered()[source]

What has been answered: per interface, the answer registered for each class.

Return type:

dict[type[Answer], dict[type, Answer]]

choice[C: type](interface: type)[source]

Mark a final as one a study may name for the Choice interface. Nothing is registered and the class is returned as it is: only that it is a final of interface is checked, so every choice on offer is found by searching for the mark.

Return type:

Callable[[C], C]

is_about(cls: type, about: Any)[source]

Whether cls is one of what about says: a subclass of a class (or of what a type alias names), any class for a protocol, met by shape.

Return type:

bool

class AnsweredTwice(interface: str, about: str, first: str, second: str)[source]

Bases: Violation

interface: str
about: str
first: str
second: str
template: AbstractClassVar[str] = '{about} has the {interface} answer {first} already, so {second} is refused: which one answers would be chosen by import order'

e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’

Type:

Wording

class AnswerAndChoice(about: str)[source]

Bases: Violation

about: str
template: AbstractClassVar[str] = '{about} is both an `Answer` and a `Choice`: one right answer is registered, several are named by a study, and nothing is both'

e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’

Type:

Wording

class AnswerHolds(answer: str, held: tuple[str, ...])[source]

Bases: Violation

answer: str
held: tuple[str, ...]
template: AbstractClassVar[str] = '{answer} holds the fields {held}: an answer is built by the registry, `cls()`, so whatever it needs is a class attribute or a method'

e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’

Type:

Wording

class ChoiceAbstract(choice: str, interface: str, abstract: tuple[str, ...])[source]

Bases: Violation

choice: str
interface: str
abstract: tuple[str, ...]
template: AbstractClassVar[str] = '{choice} leaves {abstract} abstract, so it is not a {interface} a study can name: `@choice` marks a final'

e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’

Type:

Wording

class ChoiceElsewhere(choice: str, interface: str)[source]

Bases: Violation

choice: str
interface: str
template: AbstractClassVar[str] = '{choice} is marked a {interface} choice but does not extend {interface}'

e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’

Type:

Wording

class NotAChoice(interface: str)[source]

Bases: Violation

interface: str
template: AbstractClassVar[str] = '{interface} is not a `Choice` interface: `@choice` names a level directly under `Choice`'

e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’

Type:

Wording

class AboutNothing(interface: str)[source]

Bases: Violation

interface: str
template: AbstractClassVar[str] = '{interface} does not say what it is answered per: bind `about` on it, a class, a type alias, a protocol or a tuple of those'

e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’

Type:

Wording

class NotAbout(interface: str, classes: tuple, about: str)[source]

Bases: Violation

interface: str
classes: tuple
about: str
template: AbstractClassVar[str] = '{interface} is answered per {about}, and {classes!r} is not: an answer is registered for what its interface is about'

e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’

Type:

Wording

class NotOneInterface(answer: str, interfaces: tuple[str, ...])[source]

Bases: Violation

answer: str
interfaces: tuple[str, ...]
template: AbstractClassVar[str] = '{answer} is under the interfaces {interfaces}: an answer is registered under one, a level directly under `Answer`'

e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’

Type:

Wording

class Unanswered(interface: str, about: str)[source]

Bases: Violation

interface: str
about: str
template: AbstractClassVar[str] = '{about} has no {interface} answer: import the module that registers one (`@answers`)'

e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’

Type:

Wording