[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/python/python-docs-de/3.14/library/annotationlib.po [Back]  [Original]

# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2001 Python Software Foundation
# This file is distributed under the same license as the Python package.
# FIRST AUTHOR , YEAR.
#
# Translators:
# Swen Bachmann, 2026
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Python 3.14\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-28 03:11+0000\n"
"PO-Revision-Date: 2026-05-08 17:17+0000\n"
"Last-Translator: Swen Bachmann, 2026\n"
"Language-Team: German (https://app.transifex.com/python-doc/teams/5390/de/)\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: ../../library/annotationlib.rst:2
msgid ":mod:`!annotationlib` --- Functionality for introspecting annotations"
msgstr ""

#: ../../library/annotationlib.rst:9
msgid "**Source code:** :source:`Lib/annotationlib.py`"
msgstr ""

#: ../../library/annotationlib.rst:18
msgid ""
"The :mod:`!annotationlib` module provides tools for introspecting :term:"
"`annotations ` on modules, classes, and functions."
msgstr ""

#: ../../library/annotationlib.rst:21
msgid ""
"Annotations are :ref:`lazily evaluated ` and often contain "
"forward references to objects that are not yet defined when the annotation "
"is created. This module provides a set of low-level tools that can be used "
"to retrieve annotations in a reliable way, even in the presence of forward "
"references and other edge cases."
msgstr ""

#: ../../library/annotationlib.rst:26
msgid ""
"This module supports retrieving annotations in three main formats (see :"
"class:`Format`), each of which works best for different use cases:"
msgstr ""

#: ../../library/annotationlib.rst:29
msgid ""
":attr:`~Format.VALUE` evaluates the annotations and returns their value. "
"This is most straightforward to work with, but it may raise errors, for "
"example if the annotations contain references to undefined names."
msgstr ""

#: ../../library/annotationlib.rst:32
msgid ""
":attr:`~Format.FORWARDREF` returns :class:`ForwardRef` objects for "
"annotations that cannot be resolved, allowing you to inspect the annotations "
"without evaluating them. This is useful when you need to work with "
"annotations that may contain unresolved forward references."
msgstr ""

#: ../../library/annotationlib.rst:36
msgid ""
":attr:`~Format.STRING` returns the annotations as a string, similar to how "
"it would appear in the source file. This is useful for documentation "
"generators that want to display annotations in a readable way."
msgstr ""

#: ../../library/annotationlib.rst:40
msgid ""
"The :func:`get_annotations` function is the main entry point for retrieving "
"annotations. Given a function, class, or module, it returns an annotations "
"dictionary in the requested format. This module also provides functionality "
"for working directly with the :term:`annotate function` that is used to "
"evaluate annotations, such as :func:`get_annotate_from_class_namespace` and :"
"func:`call_annotate_function`, as well as the :func:`call_evaluate_function` "
"function for working with :term:`evaluate functions `."
msgstr ""

#: ../../library/annotationlib.rst:51
msgid ""
"Most functionality in this module can execute arbitrary code; see :ref:`the "
"security section ` for more information."
msgstr ""

#: ../../library/annotationlib.rst:56
msgid ""
":pep:`649` proposed the current model for how annotations work in Python."
msgstr ""

#: ../../library/annotationlib.rst:58
msgid ""
":pep:`749` expanded on various aspects of :pep:`649` and introduced the :mod:"
"`!annotationlib` module."
msgstr ""

#: ../../library/annotationlib.rst:61
msgid ""
":ref:`annotations-howto` provides best practices for working with "
"annotations."
msgstr ""

#: ../../library/annotationlib.rst:64
msgid ""
":pypi:`typing-extensions` provides a backport of :func:`get_annotations` "
"that works on earlier versions of Python."
msgstr ""

#: ../../library/annotationlib.rst:68
msgid "Annotation semantics"
msgstr ""

#: ../../library/annotationlib.rst:70
msgid ""
"The way annotations are evaluated has changed over the history of Python 3, "
"and currently still depends on a :ref:`future import `. There have "
"been execution models for annotations:"
msgstr ""

#: ../../library/annotationlib.rst:74
msgid ""
"*Stock semantics* (default in Python 3.0 through 3.13; see :pep:`3107` and :"
"pep:`526`): Annotations are evaluated eagerly, as they are encountered in "
"the source code."
msgstr ""

#: ../../library/annotationlib.rst:77
msgid ""
"*Stringified annotations* (used with ``from __future__ import annotations`` "
"in Python 3.7 and newer; see :pep:`563`): Annotations are stored as strings "
"only."
msgstr ""

#: ../../library/annotationlib.rst:80
msgid ""
"*Deferred evaluation* (default in Python 3.14 and newer; see :pep:`649` and :"
"pep:`749`): Annotations are evaluated lazily, only when they are accessed."
msgstr ""

#: ../../library/annotationlib.rst:83
msgid "As an example, consider the following program::"
msgstr ""

#: ../../library/annotationlib.rst:85
msgid ""
"def func(a: Cls) -> None:\n"
"    print(a)\n"
"\n"
"class Cls: pass\n"
"\n"
"print(func.__annotations__)"
msgstr ""

#: ../../library/annotationlib.rst:92
msgid "This will behave as follows:"
msgstr ""

#: ../../library/annotationlib.rst:94
msgid ""
"Under stock semantics (Python 3.13 and earlier), it will throw a :exc:"
"`NameError` at the line where ``func`` is defined, because ``Cls`` is an "
"undefined name at that point."
msgstr ""

#: ../../library/annotationlib.rst:97
msgid ""
"Under stringified annotations (if ``from __future__ import annotations`` is "
"used), it will print ``{'a': 'Cls', 'return': 'None'}``."
msgstr ""

#: ../../library/annotationlib.rst:99
msgid ""
"Under deferred evaluation (Python 3.14 and later), it will print ``{'a': "
", 'return': None}``."
msgstr ""

#: ../../library/annotationlib.rst:102
msgid ""
"Stock semantics were used when function annotations were first introduced in "
"Python 3.0 (by :pep:`3107`) because this was the simplest, most obvious way "
"to implement annotations. The same execution model was used when variable "
"annotations were introduced in Python 3.6 (by :pep:`526`). However, stock "
"semantics caused problems when using annotations as type hints, such as a "
"need to refer to names that are not yet defined when the annotation is "
"encountered. In addition, there were performance problems with executing "
"annotations at module import time. Therefore, in Python 3.7, :pep:`563` "
"introduced the ability to store annotations as strings using the ``from "
"__future__ import annotations`` syntax. The plan at the time was to "
"eventually make this behavior the default, but a problem appeared: "
"stringified annotations are more difficult to process for those who "
"introspect annotations at runtime. An alternative proposal, :pep:`649`, "
"introduced the third execution model, deferred evaluation, and was "
"implemented in Python 3.14. Stringified annotations are still used if ``from "
"__future__ import annotations`` is present, but this behavior will "
"eventually be removed."
msgstr ""

#: ../../library/annotationlib.rst:121
msgid "Classes"
msgstr "Klassen"

#: ../../library/annotationlib.rst:125
msgid ""
"An :class:`~enum.IntEnum` describing the formats in which annotations can be "
"returned. Members of the enum, or their equivalent integer values, can be "
"passed to :func:`get_annotations` and other functions in this module, as "
"well as to :attr:`~object.__annotate__` functions."
msgstr ""

#: ../../library/annotationlib.rst:133
msgid "Values are the result of evaluating the annotation expressions."
msgstr ""

#: ../../library/annotationlib.rst:138
msgid ""
"Special value used to signal that an annotate function is being evaluated in "
"a special environment with fake globals. When passed this value, annotate "
"functions should either return the same value as for the :attr:`Format."
"VALUE` format, or raise :exc:`NotImplementedError` to signal that they do "
"not support execution in this environment. This format is only used "
"internally and should not be passed to the functions in this module."
msgstr ""

#: ../../library/annotationlib.rst:149
msgid ""
"Values are real annotation values (as per :attr:`Format.VALUE` format) for "
"defined values, and :class:`ForwardRef` proxies for undefined values. Real "
"objects may contain references to :class:`ForwardRef` proxy objects."
msgstr ""

#: ../../library/annotationlib.rst:157
msgid ""
"Values are the text string of the annotation as it appears in the source "
"code, up to modifications including, but not restricted to, whitespace "
"normalizations and constant values optimizations."
msgstr ""

#: ../../library/annotationlib.rst:161
msgid ""
"The exact values of these strings may change in future versions of Python."
msgstr ""

#: ../../library/annotationlib.rst:167
msgid "A proxy object for forward references in annotations."
msgstr ""

#: ../../library/annotationlib.rst:169
msgid ""
"Instances of this class are returned when the :attr:`~Format.FORWARDREF` "
"format is used and annotations contain a name that cannot be resolved. This "
"can happen when a forward reference is used in an annotation, such as when a "
"class is referenced before it is defined."
msgstr ""

#: ../../library/annotationlib.rst:176
msgid ""
"A string containing the code that was evaluated to produce the :class:"
"`~ForwardRef`. The string may not be exactly equivalent to the original "
"source."
msgstr ""

#: ../../library/annotationlib.rst:182
msgid "Evaluate the forward reference, returning its value."
msgstr ""

#: ../../library/annotationlib.rst:184
msgid ""
"If the *format* argument is :attr:`~Format.VALUE` (the default), this method "
"may throw an exception, such as :exc:`NameError`, if the forward reference "
"refers to a name that cannot be resolved. The arguments to this method can "
"be used to provide bindings for names that would otherwise be undefined. If "
"the *format* argument is :attr:`~Format.FORWARDREF`, the method will never "
"throw an exception, but may return a :class:`~ForwardRef` instance. For "
"example, if the forward reference object contains the code "
"``list[undefined]``, where ``undefined`` is a name that is not defined, "
"evaluating it with the :attr:`~Format.FORWARDREF` format will return "
"``list[ForwardRef('undefined')]``. If the *format* argument is :attr:"
"`~Format.STRING`, the method will return :attr:`~ForwardRef.__forward_arg__`."
msgstr ""

#: ../../library/annotationlib.rst:196
msgid ""
"The *owner* parameter provides the preferred mechanism for passing scope "
"information to this method. The owner of a :class:`~ForwardRef` is the "
"object that contains the annotation from which the :class:`~ForwardRef` "
"derives, such as a module object, type object, or function object."
msgstr ""

#: ../../library/annotationlib.rst:201
msgid ""
"The *globals*, *locals*, and *type_params* parameters provide a more precise "
"mechanism for influencing the names that are available when the :class:"
"`~ForwardRef` is evaluated. *globals* and *locals* are passed to :func:"
"`eval`, representing the global and local namespaces in which the name is "
"evaluated. The *type_params* parameter is relevant for objects created using "
"the native syntax for :ref:`generic classes ` and :ref:"
"`functions `. It is a tuple of :ref:`type parameters "
"` that are in scope while the forward reference is being "
"evaluated. For example, if evaluating a :class:`~ForwardRef` retrieved from "
"an annotation found in the class namespace of a generic class ``C``, "
"*type_params* should be set to ``C.__type_params__``."
msgstr ""

#: ../../library/annotationlib.rst:212
msgid ""
":class:`~ForwardRef` instances returned by :func:`get_annotations` retain "
"references to information about the scope they originated from, so calling "
"this method with no further arguments may be sufficient to evaluate such "
"objects. :class:`~ForwardRef` instances created by other means may not have "
"any information about their scope, so passing arguments to this method may "
"be necessary to evaluate them successfully."
msgstr ""

#: ../../library/annotationlib.rst:219
msgid ""
"If no *owner*, *globals*, *locals*, or *type_params* are provided and the :"
"class:`~ForwardRef` does not contain information about its origin, empty "
"globals and locals dictionaries are used."
msgstr ""

#: ../../library/annotationlib.rst:227
msgid "Functions"
msgstr "Funktionen"

#: ../../library/annotationlib.rst:231
msgid ""
"Convert an annotations dict containing runtime values to a dict containing "
"only strings. If the values are not already strings, they are converted "
"using :func:`type_repr`. This is meant as a helper for user-provided "
"annotate functions that support the :attr:`~Format.STRING` format but do not "
"have access to the code creating the annotations."
msgstr ""

#: ../../library/annotationlib.rst:238
msgid ""
"For example, this is used to implement the :attr:`~Format.STRING` format "
"for :class:`typing.TypedDict` classes created through the functional syntax:"
msgstr ""

#: ../../library/annotationlib.rst:241
msgid ""
">>> from typing import TypedDict\n"
">>> Movie = TypedDict(\"movie\", {\"name\": str, \"year\": int})\n"
">>> get_annotations(Movie, format=Format.STRING)\n"
"{'name': 'str', 'year': 'int'}"
msgstr ""

#: ../../library/annotationlib.rst:252
msgid ""
"Call the :term:`annotate function` *annotate* with the given *format*, a "
"member of the :class:`Format` enum, and return the annotations dictionary "
"produced by the function."
msgstr ""

#: ../../library/annotationlib.rst:256
msgid ""
"This helper function is required because annotate functions generated by the "
"compiler for functions, classes, and modules only support the :attr:`~Format."
"VALUE` format when called directly. To support other formats, this function "
"calls the annotate function in a special environment that allows it to "
"produce annotations in the other formats. This is a useful building block "
"when implementing functionality that needs to partially evaluate annotations "
"while a class is being constructed."
msgstr ""

#: ../../library/annotationlib.rst:265
msgid ""
"*owner* is the object that owns the annotation function, usually a function, "
"class, or module. If provided, it is used in the :attr:`~Format.FORWARDREF` "
"format to produce a :class:`ForwardRef` object that carries more information."
msgstr ""

#: ../../library/annotationlib.rst:272
msgid ""
":PEP:`PEP 649 ` "
"contains an explanation of the implementation technique used by this "
"function."
msgstr ""

#: ../../library/annotationlib.rst:280
msgid ""
"Call the :term:`evaluate function` *evaluate* with the given *format*, a "
"member of the :class:`Format` enum, and return the value produced by the "
"function. This is similar to :func:`call_annotate_function`, but the latter "
"always returns a dictionary mapping strings to annotations, while this "
"function returns a single value."
msgstr ""

#: ../../library/annotationlib.rst:286
msgid ""
"This is intended for use with the evaluate functions generated for lazily "
"evaluated elements related to type aliases and type parameters:"
msgstr ""

#: ../../library/annotationlib.rst:289
msgid ":meth:`typing.TypeAliasType.evaluate_value`, the value of type aliases"
msgstr ""

#: ../../library/annotationlib.rst:290
msgid ":meth:`typing.TypeVar.evaluate_bound`, the bound of type variables"
msgstr ""

#: ../../library/annotationlib.rst:291
msgid ""
":meth:`typing.TypeVar.evaluate_constraints`, the constraints of type "
"variables"
msgstr ""

#: ../../library/annotationlib.rst:293
msgid ""
":meth:`typing.TypeVar.evaluate_default`, the default value of type variables"
msgstr ""

#: ../../library/annotationlib.rst:295
msgid ""
":meth:`typing.ParamSpec.evaluate_default`, the default value of parameter "
"specifications"
msgstr ""

#: ../../library/annotationlib.rst:297
msgid ""
":meth:`typing.TypeVarTuple.evaluate_default`, the default value of type "
"variable tuples"
msgstr ""

#: ../../library/annotationlib.rst:300
msgid ""
"*owner* is the object that owns the evaluate function, such as the type "
"alias or type variable object."
msgstr ""

#: ../../library/annotationlib.rst:303
msgid ""
"*format* can be used to control the format in which the value is returned:"
msgstr ""

#: ../../library/annotationlib.rst:305
msgid ""
">>> type Alias = undefined\n"
">>> call_evaluate_function(Alias.evaluate_value, Format.VALUE)\n"
"Traceback (most recent call last):\n"
"...\n"
"NameError: name 'undefined' is not defined\n"
">>> call_evaluate_function(Alias.evaluate_value, Format.FORWARDREF)\n"
"ForwardRef('undefined')\n"
">>> call_evaluate_function(Alias.evaluate_value, Format.STRING)\n"
"'undefined'"
msgstr ""

#: ../../library/annotationlib.rst:321
msgid ""
"Retrieve the :term:`annotate function` from a class namespace dictionary "
"*namespace*. Return :const:`!None` if the namespace does not contain an "
"annotate function. This is primarily useful before the class has been fully "
"created (e.g., in a metaclass); after the class exists, the annotate "
"function can be retrieved with ``cls.__annotate__``. See :ref:`below "
"` for an example using this function in a metaclass."
msgstr ""

#: ../../library/annotationlib.rst:331
msgid "Compute the annotations dict for an object."
msgstr ""

#: ../../library/annotationlib.rst:333
msgid ""
"*obj* may be a callable, class, module, or other object with :attr:`~object."
"__annotate__` or :attr:`~object.__annotations__` attributes. Passing any "
"other object raises :exc:`TypeError`."
msgstr ""

#: ../../library/annotationlib.rst:337
msgid ""
"The *format* parameter controls the format in which annotations are "
"returned, and must be a member of the :class:`Format` enum or its integer "
"equivalent. The different formats work as follows:"
msgstr ""

#: ../../library/annotationlib.rst:341
msgid ""
"VALUE: :attr:`!object.__annotations__` is tried first; if that does not "
"exist, the :attr:`!object.__annotate__` function is called if it exists."
msgstr ""

#: ../../library/annotationlib.rst:344
msgid ""
"FORWARDREF: If :attr:`!object.__annotations__` exists and can be evaluated "
"successfully, it is used; otherwise, the :attr:`!object.__annotate__` "
"function is called. If it does not exist either, :attr:`!object."
"__annotations__` is tried again and any error from accessing it is re-raised."
msgstr ""

#: ../../library/annotationlib.rst:349
msgid ""
"When calling :attr:`!object.__annotate__` it is first called with :attr:"
"`~Format.FORWARDREF`. If this is not implemented, it will then check if :"
"attr:`~Format.VALUE_WITH_FAKE_GLOBALS` is supported and use that in the fake "
"globals environment. If neither of these formats are supported, it will fall "
"back to using :attr:`~Format.VALUE`. If :attr:`~Format.VALUE` fails, the "
"error from this call will be raised."
msgstr ""

#: ../../library/annotationlib.rst:355
msgid ""
"STRING: If :attr:`!object.__annotate__` exists, it is called first; "
"otherwise, :attr:`!object.__annotations__` is used and stringified using :"
"func:`annotations_to_string`."
msgstr ""

#: ../../library/annotationlib.rst:359
msgid ""
"When calling :attr:`!object.__annotate__` it is first called with :attr:"
"`~Format.STRING`. If this is not implemented, it will then check if :attr:"
"`~Format.VALUE_WITH_FAKE_GLOBALS` is supported and use that in the fake "
"globals environment. If neither of these formats are supported, it will fall "
"back to using :attr:`~Format.VALUE` with the result converted using :func:"
"`annotations_to_string`. If :attr:`~Format.VALUE` fails, the error from this "
"call will be raised."
msgstr ""

#: ../../library/annotationlib.rst:366
msgid ""
"Returns a dict. :func:`!get_annotations` returns a new dict every time it's "
"called; calling it twice on the same object will return two different but "
"equivalent dicts."
msgstr ""

#: ../../library/annotationlib.rst:370
msgid "This function handles several details for you:"
msgstr ""

#: ../../library/annotationlib.rst:372
msgid ""
"If *eval_str* is true, values of type :class:`!str` will be un-stringized "
"using :func:`eval`. This is intended for use with stringized annotations "
"(``from __future__ import annotations``). It is an error to set *eval_str* "
"to true with formats other than :attr:`Format.VALUE`."
msgstr ""

#: ../../library/annotationlib.rst:377
msgid ""
"If *obj* doesn't have an annotations dict, returns an empty dict. (Functions "
"and methods always have an annotations dict; classes, modules, and other "
"types of callables may not.)"
msgstr ""

#: ../../library/annotationlib.rst:381
msgid ""
"Ignores inherited annotations on classes, as well as annotations on "
"metaclasses. If a class doesn't have its own annotations dict, returns an "
"empty dict."
msgstr ""

#: ../../library/annotationlib.rst:384
msgid ""
"All accesses to object members and dict values are done using ``getattr()`` "
"and ``dict.get()`` for safety."
msgstr ""

#: ../../library/annotationlib.rst:387
msgid ""
"*eval_str* controls whether or not values of type :class:`!str` are replaced "
"with the result of calling :func:`eval` on those values:"
msgstr ""

#: ../../library/annotationlib.rst:390
msgid ""
"If eval_str is true, :func:`eval` is called on values of type :class:`!str`. "
"(Note that :func:`!get_annotations` doesn't catch exceptions; if :func:"
"`eval` raises an exception, it will unwind the stack past the :func:`!"
"get_annotations` call.)"
msgstr ""

#: ../../library/annotationlib.rst:394
msgid ""
"If *eval_str* is false (the default), values of type :class:`!str` are "
"unchanged."
msgstr ""

#: ../../library/annotationlib.rst:397
msgid ""
"*globals* and *locals* are passed in to :func:`eval`; see the documentation "
"for :func:`eval` for more information. If *globals* or *locals* is :const:`!"
"None`, this function may replace that value with a context-specific default, "
"contingent on ``type(obj)``:"
msgstr ""

#: ../../library/annotationlib.rst:402
msgid "If *obj* is a module, *globals* defaults to ``obj.__dict__``."
msgstr ""

#: ../../library/annotationlib.rst:403
msgid ""
"If *obj* is a class, *globals* defaults to ``sys.modules[obj.__module__]."
"__dict__`` and *locals* defaults to the *obj* class namespace."
msgstr ""

#: ../../library/annotationlib.rst:406
msgid ""
"If *obj* is a callable, *globals* defaults to :attr:`obj.__globals__ "
"`, although if *obj* is a wrapped function (using :"
"func:`functools.update_wrapper`) or a :class:`functools.partial` object, it "
"is unwrapped until a non-wrapped function is found."
msgstr ""

#: ../../library/annotationlib.rst:412
msgid ""
"Calling :func:`!get_annotations` is best practice for accessing the "
"annotations dict of any object. See :ref:`annotations-howto` for more "
"information on annotations best practices."
msgstr ""

#: ../../library/annotationlib.rst:416
msgid ""
">>> def f(a: int, b: str) -> float:\n"
"...     pass\n"
">>> get_annotations(f)\n"
"{'a': , 'b': , 'return': }"
msgstr ""

#: ../../library/annotationlib.rst:427
msgid ""
"Convert an arbitrary Python value to a format suitable for use by the :attr:"
"`~Format.STRING` format. This calls :func:`repr` for most objects, but has "
"special handling for some objects, such as type objects."
msgstr ""

#: ../../library/annotationlib.rst:431
msgid ""
"This is meant as a helper for user-provided annotate functions that support "
"the :attr:`~Format.STRING` format but do not have access to the code "
"creating the annotations. It can also be used to provide a user-friendly "
"string representation for other objects that contain values that are "
"commonly encountered in annotations."
msgstr ""

#: ../../library/annotationlib.rst:441
msgid "Recipes"
msgstr ""

#: ../../library/annotationlib.rst:446
msgid "Using annotations in a metaclass"
msgstr ""

#: ../../library/annotationlib.rst:448
msgid ""
"A :ref:`metaclass ` may want to inspect or even modify the "
"annotations in a class body during class creation. Doing so requires "
"retrieving annotations from the class namespace dictionary. For classes "
"created with ``from __future__ import annotations``, the annotations will be "
"in the ``__annotations__`` key of the dictionary. For other classes with "
"annotations, :func:`get_annotate_from_class_namespace` can be used to get "
"the annotate function, and :func:`call_annotate_function` can be used to "
"call it and retrieve the annotations. Using the :attr:`~Format.FORWARDREF` "
"format will usually be best, because this allows the annotations to refer to "
"names that cannot yet be resolved when the class is created."
msgstr ""

#: ../../library/annotationlib.rst:459
msgid ""
"To modify the annotations, it is best to create a wrapper annotate function "
"that calls the original annotate function, makes any necessary adjustments, "
"and returns the result."
msgstr ""

#: ../../library/annotationlib.rst:463
msgid ""
"Below is an example of a metaclass that filters out all :class:`typing."
"ClassVar` annotations from the class and puts them in a separate attribute:"
msgstr ""

#: ../../library/annotationlib.rst:466
msgid ""
"import annotationlib\n"
"import typing\n"
"\n"
"class ClassVarSeparator(type):\n"
"   def __new__(mcls, name, bases, ns):\n"
"      if \"__annotations__\" in ns:  # from __future__ import annotations\n"
"         annotations = ns[\"__annotations__\"]\n"
"         classvar_keys = {\n"
"            key for key, value in annotations.items()\n"
"            # Use string comparison for simplicity; a more robust solution\n"
"            # could use annotationlib.ForwardRef.evaluate\n"
"            if value.startswith(\"ClassVar\")\n"
"         }\n"
"         classvars = {key: annotations[key] for key in classvar_keys}\n"
"         ns[\"__annotations__\"] = {\n"
"            key: value for key, value in annotations.items()\n"
"            if key not in classvar_keys\n"
"         }\n"
"         wrapped_annotate = None\n"
"      elif annotate := annotationlib.get_annotate_from_class_namespace(ns):\n"
"         annotations = annotationlib.call_annotate_function(\n"
"            annotate, format=annotationlib.Format.FORWARDREF\n"
"         )\n"
"         classvar_keys = {\n"
"            key for key, value in annotations.items()\n"
"            if typing.get_origin(value) is typing.ClassVar\n"
"         }\n"
"         classvars = {key: annotations[key] for key in classvar_keys}\n"
"\n"
"         def wrapped_annotate(format):\n"
"            annos = annotationlib.call_annotate_function(annotate, format, "
"owner=typ)\n"
"            return {key: value for key, value in annos.items() if key not in "
"classvar_keys}\n"
"\n"
"      else:  # no annotations\n"
"         classvars = {}\n"
"         wrapped_annotate = None\n"
"      typ = super().__new__(mcls, name, bases, ns)\n"
"\n"
"      if wrapped_annotate is not None:\n"
"         # Wrap the original __annotate__ with a wrapper that removes "
"ClassVars\n"
"         typ.__annotate__ = wrapped_annotate\n"
"      typ.classvars = classvars  # Store the ClassVars in a separate "
"attribute\n"
"      return typ"
msgstr ""

#: ../../library/annotationlib.rst:514
msgid "Creating a custom callable annotate function"
msgstr ""

#: ../../library/annotationlib.rst:516
msgid ""
"Custom :term:`annotate functions ` may be literal "
"functions like those automatically generated for functions, classes, and "
"modules. Or, they may wish to utilise the encapsulation provided by classes, "
"in which case any :term:`callable` can be used as an :term:`annotate "
"function`."
msgstr ""

#: ../../library/annotationlib.rst:521
msgid ""
"To provide the :attr:`~Format.VALUE`, :attr:`~Format.STRING`, or :attr:"
"`~Format.FORWARDREF` formats directly, an :term:`annotate function` must "
"provide the following attribute:"
msgstr ""

#: ../../library/annotationlib.rst:525
msgid ""
"A callable ``__call__`` with signature ``__call__(format, /) -> dict``, that "
"does not raise a :exc:`NotImplementedError` when called with a supported "
"format."
msgstr ""

#: ../../library/annotationlib.rst:528
msgid ""
"To provide the :attr:`~Format.VALUE_WITH_FAKE_GLOBALS` format, which is used "
"to automatically generate :attr:`~Format.STRING` or :attr:`~Format."
"FORWARDREF` if they are not supported directly, :term:`annotate functions "
"` must provide the following attributes:"
msgstr ""

#: ../../library/annotationlib.rst:533
msgid ""
"A callable ``__call__`` with signature ``__call__(format, /) -> dict``, that "
"does not raise a :exc:`NotImplementedError` when called with :attr:`~Format."
"VALUE_WITH_FAKE_GLOBALS`."
msgstr ""

#: ../../library/annotationlib.rst:536
msgid ""
"A :ref:`code object ` ``__code__`` containing the compiled "
"code for the annotate function."
msgstr ""

#: ../../library/annotationlib.rst:538
msgid ""
"Optional: A tuple of the function's positional defaults ``__kwdefaults__``, "
"if the function represented by ``__code__`` uses any positional defaults."
msgstr ""

#: ../../library/annotationlib.rst:540
msgid ""
"Optional: A dict of the function's keyword defaults ``__defaults__``, if the "
"function represented by ``__code__`` uses any keyword defaults."
msgstr ""

#: ../../library/annotationlib.rst:542
msgid "Optional: All other :ref:`function attributes `."
msgstr ""

#: ../../library/annotationlib.rst:544
msgid ""
"class Annotate:\n"
"    called_formats = []\n"
"\n"
"    def __call__(self, format=None, /, *, _self=None):\n"
"        # When called with fake globals, `_self` will be the\n"
"        # actual self value, and `self` will be the format.\n"
"        if _self is not None:\n"
"            self, format = _self, self\n"
"\n"
"        self.called_formats.append(format)\n"
"        if format >> from annotationlib import call_annotate_function, Format\n"
">>> call_annotate_function(Annotate(), format=Format.STRING)\n"
"{'x': 'MyType'}"
msgstr ""

#: ../../library/annotationlib.rst:576
msgid "Or used as the annotate function for an object:"
msgstr ""

#: ../../library/annotationlib.rst:578
msgid ""
">>> from annotationlib import get_annotations, Format\n"
">>> class C:\n"
"...   pass\n"
">>> C.__annotate__ = Annotate()\n"
">>> get_annotations(Annotate(), format=Format.STRING)\n"
"{'x': 'MyType'}"
msgstr ""

#: ../../library/annotationlib.rst:589
msgid "Limitations of the ``STRING`` format"
msgstr ""

#: ../../library/annotationlib.rst:591
msgid ""
"The :attr:`~Format.STRING` format is meant to approximate the source code of "
"the annotation, but the implementation strategy used means that it is not "
"always possible to recover the exact source code."
msgstr ""

#: ../../library/annotationlib.rst:595
msgid ""
"First, the stringifier of course cannot recover any information that is not "
"present in the compiled code, including comments, whitespace, "
"parenthesization, and operations that get simplified by the compiler."
msgstr ""

#: ../../library/annotationlib.rst:599
msgid ""
"Second, the stringifier can intercept almost all operations that involve "
"names looked up in some scope, but it cannot intercept operations that "
"operate fully on constants. As a corollary, this also means it is not safe "
"to request the ``STRING`` format on untrusted code: Python is powerful "
"enough that it is possible to achieve arbitrary code execution even with no "
"access to any globals or builtins. For example:"
msgstr ""

#: ../../library/annotationlib.rst:605
msgid ""
">>> def f(x: (1).__class__.__base__.__subclasses__()[-1].__init__."
"__builtins__[\"print\"](\"Hello world\")): pass\n"
"...\n"
">>> annotationlib.get_annotations(f, format=annotationlib.Format.STRING)\n"
"Hello world\n"
"{'x': 'None'}"
msgstr ""

#: ../../library/annotationlib.rst:614
msgid ""
"This particular example works as of the time of writing, but it relies on "
"implementation details and is not guaranteed to work in the future."
msgstr ""

#: ../../library/annotationlib.rst:617
msgid ""
"Among the different kinds of expressions that exist in Python, as "
"represented by the :mod:`ast` module, some expressions are supported, "
"meaning that the ``STRING`` format can generally recover the original source "
"code; others are unsupported, meaning that they may result in incorrect "
"output or an error."
msgstr ""

#: ../../library/annotationlib.rst:622
msgid "The following are supported (sometimes with caveats):"
msgstr ""

#: ../../library/annotationlib.rst:624
msgid ":class:`ast.BinOp`"
msgstr ""

#: ../../library/annotationlib.rst:625
msgid ":class:`ast.UnaryOp`"
msgstr ""

#: ../../library/annotationlib.rst:627
msgid ""
":class:`ast.Invert` (``~``), :class:`ast.UAdd` (``+``), and :class:`ast."
"USub` (``-``) are supported"
msgstr ""

#: ../../library/annotationlib.rst:628
msgid ":class:`ast.Not` (``not``) is not supported"
msgstr ""

#: ../../library/annotationlib.rst:630
msgid ":class:`ast.Dict` (except when using ``**`` unpacking)"
msgstr ""

#: ../../library/annotationlib.rst:631
msgid ":class:`ast.Set`"
msgstr ""

#: ../../library/annotationlib.rst:632
msgid ":class:`ast.Compare`"
msgstr ""

#: ../../library/annotationlib.rst:634
msgid ":class:`ast.Eq` and :class:`ast.NotEq` are supported"
msgstr ""

#: ../../library/annotationlib.rst:635
msgid ""
":class:`ast.Lt`, :class:`ast.LtE`, :class:`ast.Gt`, and :class:`ast.GtE` are "
"supported, but the operand may be flipped"
msgstr ""

#: ../../library/annotationlib.rst:636
msgid ""
":class:`ast.Is`, :class:`ast.IsNot`, :class:`ast.In`, and :class:`ast.NotIn` "
"are not supported"
msgstr ""

#: ../../library/annotationlib.rst:638
msgid ":class:`ast.Call` (except when using ``**`` unpacking)"
msgstr ""

#: ../../library/annotationlib.rst:639
msgid ""
":class:`ast.Constant` (though not the exact representation of the constant; "
"for example, escape sequences in strings are lost; hexadecimal numbers are "
"converted to decimal)"
msgstr ""

#: ../../library/annotationlib.rst:641
msgid ":class:`ast.Attribute` (assuming the value is not a constant)"
msgstr ""

#: ../../library/annotationlib.rst:642
msgid ":class:`ast.Subscript` (assuming the value is not a constant)"
msgstr ""

#: ../../library/annotationlib.rst:643
msgid ":class:`ast.Starred` (``*`` unpacking)"
msgstr ""

#: ../../library/annotationlib.rst:644
msgid ":class:`ast.Name`"
msgstr ""

#: ../../library/annotationlib.rst:645
msgid ":class:`ast.List`"
msgstr ""

#: ../../library/annotationlib.rst:646
msgid ":class:`ast.Tuple`"
msgstr ""

#: ../../library/annotationlib.rst:647
msgid ":class:`ast.Slice`"
msgstr ""

#: ../../library/annotationlib.rst:649
msgid ""
"The following are unsupported, but throw an informative error when "
"encountered by the stringifier:"
msgstr ""

#: ../../library/annotationlib.rst:652
msgid ""
":class:`ast.FormattedValue` (f-strings; error is not detected if conversion "
"specifiers like ``!r`` are used)"
msgstr ""

#: ../../library/annotationlib.rst:654
msgid ":class:`ast.JoinedStr` (f-strings)"
msgstr ""

#: ../../library/annotationlib.rst:656
msgid "The following are unsupported and result in incorrect output:"
msgstr ""

#: ../../library/annotationlib.rst:658
msgid ":class:`ast.BoolOp` (``and`` and ``or``)"
msgstr ""

#: ../../library/annotationlib.rst:659
msgid ":class:`ast.IfExp`"
msgstr ""

#: ../../library/annotationlib.rst:660
msgid ":class:`ast.Lambda`"
msgstr ""

#: ../../library/annotationlib.rst:661
msgid ":class:`ast.ListComp`"
msgstr ""

#: ../../library/annotationlib.rst:662
msgid ":class:`ast.SetComp`"
msgstr ""

#: ../../library/annotationlib.rst:663
msgid ":class:`ast.DictComp`"
msgstr ""

#: ../../library/annotationlib.rst:664
msgid ":class:`ast.GeneratorExp`"
msgstr ""

#: ../../library/annotationlib.rst:666
msgid ""
"The following are disallowed in annotation scopes and therefore not relevant:"
msgstr ""

#: ../../library/annotationlib.rst:668
msgid ":class:`ast.NamedExpr` (``:=``)"
msgstr ""

#: ../../library/annotationlib.rst:669
msgid ":class:`ast.Await`"
msgstr ""

#: ../../library/annotationlib.rst:670
msgid ":class:`ast.Yield`"
msgstr ""

#: ../../library/annotationlib.rst:671
msgid ":class:`ast.YieldFrom`"
msgstr ""

#: ../../library/annotationlib.rst:675
msgid "Limitations of the ``FORWARDREF`` format"
msgstr ""

#: ../../library/annotationlib.rst:677
msgid ""
"The :attr:`~Format.FORWARDREF` format aims to produce real values as much as "
"possible, with anything that cannot be resolved replaced with :class:"
"`ForwardRef` objects. It is affected by broadly the same Limitations as the :"
"attr:`~Format.STRING` format: annotations that perform operations on "
"literals or that use unsupported expression types may raise exceptions when "
"evaluated using the :attr:`~Format.FORWARDREF` format."
msgstr ""

#: ../../library/annotationlib.rst:684
msgid "Below are a few examples of the behavior with unsupported expressions:"
msgstr ""

#: ../../library/annotationlib.rst:686
msgid ""
">>> from annotationlib import get_annotations, Format\n"
">>> def zerodiv(x: 1 / 0): ...\n"
">>> get_annotations(zerodiv, format=Format.STRING)\n"
"Traceback (most recent call last):\n"
"  ...\n"
"ZeroDivisionError: division by zero\n"
">>> get_annotations(zerodiv, format=Format.FORWARDREF)\n"
"Traceback (most recent call last):\n"
"  ...\n"
"ZeroDivisionError: division by zero\n"
">>> def ifexp(x: 1 if y else 0): ...\n"
">>> get_annotations(ifexp, format=Format.STRING)\n"
"{'x': '1'}"
msgstr ""

#: ../../library/annotationlib.rst:705
msgid "Security implications of introspecting annotations"
msgstr ""

#: ../../library/annotationlib.rst:707
msgid ""
"Much of the functionality in this module involves executing code related to "
"annotations, which can then do arbitrary things. For example, :func:"
"`get_annotations` may call an arbitrary :term:`annotate function`, and :meth:"
"`ForwardRef.evaluate` may call :func:`eval` on an arbitrary string. Code "
"contained in an annotation might make arbitrary system calls, enter an "
"infinite loop, or perform any other operation. This is also true for any "
"access of the :attr:`~object.__annotations__` attribute, and for various "
"functions in the :mod:`typing` module that work with annotations, such as :"
"func:`typing.get_type_hints`."
msgstr ""

#: ../../library/annotationlib.rst:716
msgid ""
"Any security issue arising from this also applies immediately after "
"importing code that may contain untrusted annotations: importing code can "
"always cause arbitrary operations to be performed. However, it is unsafe to "
"accept strings or other input from an untrusted source and pass them to any "
"of the APIs for introspecting annotations, for example by editing an "
"``__annotations__`` dictionary or directly creating a :class:`ForwardRef` "
"object."
msgstr ""

Web Proxy Viewer  |  New URL  |  Original Page