@@ -510,6 +510,81 @@ annotations from the class and puts them in a separate attribute:
510510 return typ
511511
512512
513+ Creating a custom callable annotate function
514+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
515+
516+ Custom :term: `annotate functions <annotate function> ` may be literal functions like those
517+ automatically generated for functions, classes, and modules. Or, they may wish to utilise
518+ the encapsulation provided by classes, in which case any :term: `callable ` can be used as
519+ an :term: `annotate function `.
520+
521+ To provide the :attr: `~Format.VALUE `, :attr: `~Format.STRING `, or
522+ :attr: `~Format.FORWARDREF ` formats directly, an :term: `annotate function ` must provide
523+ the following attribute:
524+
525+ * A callable ``__call__ `` with signature ``__call__(format, /) -> dict ``, that does not
526+ raise a :exc: `NotImplementedError ` when called with a supported format.
527+
528+ To provide the :attr: `~Format.VALUE_WITH_FAKE_GLOBALS ` format, which is used to
529+ automatically generate :attr: `~Format.STRING ` or :attr: `~Format.FORWARDREF ` if they are
530+ not supported directly, :term: `annotate functions <annotate function> ` must provide the
531+ following attributes:
532+
533+ * A callable ``__call__ `` with signature ``__call__(format, /) -> dict ``, that does not
534+ raise a :exc: `NotImplementedError ` when called with
535+ :attr: `~Format.VALUE_WITH_FAKE_GLOBALS `.
536+ * A :ref: `code object <code-objects >` ``__code__ `` containing the compiled code for the
537+ annotate function.
538+ * Optional: A tuple of the function's positional defaults ``__kwdefaults__ ``, if the
539+ function represented by ``__code__ `` uses any positional defaults.
540+ * Optional: A dict of the function's keyword defaults ``__defaults__ ``, if the function
541+ represented by ``__code__ `` uses any keyword defaults.
542+ * Optional: All other :ref: `function attributes <inspect-types >`.
543+
544+ .. code-block :: python
545+
546+ class Annotate :
547+ called_formats = []
548+
549+ def __call__ (self , format = None , / , * , _self = None ):
550+ # When called with fake globals, `_self` will be the
551+ # actual self value, and `self` will be the format.
552+ if _self is not None :
553+ self , format = _self, self
554+
555+ self .called_formats.append(format )
556+ if format <= 2 : # VALUE or VALUE_WITH_FAKE_GLOBALS
557+ return {" x" : MyType}
558+ raise NotImplementedError
559+
560+ __code__ = __call__ .__code__
561+ __defaults__ = (None ,)
562+ __kwdefaults__ = property (lambda self : dict (_self = self ))
563+
564+ __globals__ = {}
565+ __builtins__ = {}
566+ __closure__ = None
567+
568+ This can then be called with:
569+
570+ .. code-block :: pycon
571+
572+ >>> from annotationlib import call_annotate_function, Format
573+ >>> call_annotate_function(Annotate(), format=Format.STRING)
574+ {'x': 'MyType'}
575+
576+ Or used as the annotate function for an object:
577+
578+ .. code-block :: pycon
579+
580+ >>> from annotationlib import get_annotations, Format
581+ >>> class C:
582+ ... pass
583+ >>> C.__annotate__ = Annotate()
584+ >>> get_annotations(Annotate(), format=Format.STRING)
585+ {'x': 'MyType'}
586+
587+
513588 Limitations of the ``STRING `` format
514589------------------------------------
515590
0 commit comments