# Copyright (C) 2001-2018, Python Software Foundation # For licence information, see README file. # msgid "" msgstr "" "Project-Id-Version: Python 3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-09-23 16:16+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: FRENCH \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: howto/annotations.rst:5 msgid "Annotations Best Practices" msgstr "" #: howto/annotations.rst:0 msgid "author" msgstr "" #: howto/annotations.rst:7 msgid "Larry Hastings" msgstr "" #: howto/annotations.rst:None msgid "Abstract" msgstr "" #: howto/annotations.rst:11 msgid "" "This document is designed to encapsulate the best practices for working with " "annotations dicts. If you write Python code that examines " "``__annotations__`` on Python objects, we encourage you to follow the " "guidelines described below." msgstr "" #: howto/annotations.rst:16 msgid "" "The document is organized into four sections: best practices for accessing " "the annotations of an object in Python versions 3.10 and newer, best " "practices for accessing the annotations of an object in Python versions 3.9 " "and older, other best practices for ``__annotations__`` that apply to any " "Python version, and quirks of ``__annotations__``." msgstr "" #: howto/annotations.rst:26 msgid "" "Note that this document is specifically about working with " "``__annotations__``, not uses *for* annotations. If you're looking for " "information on how to use \"type hints\" in your code, please see the :mod:" "`typing` module." msgstr "" #: howto/annotations.rst:33 msgid "Accessing The Annotations Dict Of An Object In Python 3.10 And Newer" msgstr "" #: howto/annotations.rst:35 msgid "" "Python 3.10 adds a new function to the standard library: :func:`inspect." "get_annotations`. In Python versions 3.10 and newer, calling this function " "is the best practice for accessing the annotations dict of any object that " "supports annotations. This function can also \"un-stringize\" stringized " "annotations for you." msgstr "" #: howto/annotations.rst:42 msgid "" "If for some reason :func:`inspect.get_annotations` isn't viable for your use " "case, you may access the ``__annotations__`` data member manually. Best " "practice for this changed in Python 3.10 as well: as of Python 3.10, ``o." "__annotations__`` is guaranteed to *always* work on Python functions, " "classes, and modules. If you're certain the object you're examining is one " "of these three *specific* objects, you may simply use ``o.__annotations__`` " "to get at the object's annotations dict." msgstr "" #: howto/annotations.rst:52 msgid "" "However, other types of callables--for example, callables created by :func:" "`functools.partial`--may not have an ``__annotations__`` attribute defined. " "When accessing the ``__annotations__`` of a possibly unknown object, best " "practice in Python versions 3.10 and newer is to call :func:`getattr` with " "three arguments, for example ``getattr(o, '__annotations__', None)``." msgstr "" #: howto/annotations.rst:62 msgid "Accessing The Annotations Dict Of An Object In Python 3.9 And Older" msgstr "" #: howto/annotations.rst:64 msgid "" "In Python 3.9 and older, accessing the annotations dict of an object is much " "more complicated than in newer versions. The problem is a design flaw in " "these older versions of Python, specifically to do with class annotations." msgstr "" #: howto/annotations.rst:69 msgid "" "Best practice for accessing the annotations dict of other objects--" "functions, other callables, and modules--is the same as best practice for " "3.10, assuming you aren't calling :func:`inspect.get_annotations`: you " "should use three-argument :func:`getattr` to access the object's " "``__annotations__`` attribute." msgstr "" #: howto/annotations.rst:76 msgid "" "Unfortunately, this isn't best practice for classes. The problem is that, " "since ``__annotations__`` is optional on classes, and because classes can " "inherit attributes from their base classes, accessing the " "``__annotations__`` attribute of a class may inadvertently return the " "annotations dict of a *base class.* As an example::" msgstr "" #: howto/annotations.rst:92 msgid "This will print the annotations dict from ``Base``, not ``Derived``." msgstr "" #: howto/annotations.rst:95 msgid "" "Your code will have to have a separate code path if the object you're " "examining is a class (``isinstance(o, type)``). In that case, best practice " "relies on an implementation detail of Python 3.9 and before: if a class has " "annotations defined, they are stored in the class's ``__dict__`` " "dictionary. Since the class may or may not have annotations defined, best " "practice is to call the ``get`` method on the class dict." msgstr "" #: howto/annotations.rst:103 msgid "" "To put it all together, here is some sample code that safely accesses the " "``__annotations__`` attribute on an arbitrary object in Python 3.9 and " "before::" msgstr "" #: howto/annotations.rst:112 msgid "" "After running this code, ``ann`` should be either a dictionary or ``None``. " "You're encouraged to double-check the type of ``ann`` using :func:" "`isinstance` before further examination." msgstr "" #: howto/annotations.rst:117 msgid "" "Note that some exotic or malformed type objects may not have a ``__dict__`` " "attribute, so for extra safety you may also wish to use :func:`getattr` to " "access ``__dict__``." msgstr "" #: howto/annotations.rst:123 msgid "Manually Un-Stringizing Stringized Annotations" msgstr "" #: howto/annotations.rst:125 msgid "" "In situations where some annotations may be \"stringized\", and you wish to " "evaluate those strings to produce the Python values they represent, it " "really is best to call :func:`inspect.get_annotations` to do this work for " "you." msgstr "" #: howto/annotations.rst:131 msgid "" "If you're using Python 3.9 or older, or if for some reason you can't use :" "func:`inspect.get_annotations`, you'll need to duplicate its logic. You're " "encouraged to examine the implementation of :func:`inspect.get_annotations` " "in the current Python version and follow a similar approach." msgstr "" #: howto/annotations.rst:137 msgid "" "In a nutshell, if you wish to evaluate a stringized annotation on an " "arbitrary object ``o``:" msgstr "" #: howto/annotations.rst:140 msgid "" "If ``o`` is a module, use ``o.__dict__`` as the ``globals`` when calling :" "func:`eval`." msgstr "" #: howto/annotations.rst:142 msgid "" "If ``o`` is a class, use ``sys.modules[o.__module__].__dict__`` as the " "``globals``, and ``dict(vars(o))`` as the ``locals``, when calling :func:" "`eval`." msgstr "" #: howto/annotations.rst:145 msgid "" "If ``o`` is a wrapped callable using :func:`functools.update_wrapper`, :func:" "`functools.wraps`, or :func:`functools.partial`, iteratively unwrap it by " "accessing either ``o.__wrapped__`` or ``o.func`` as appropriate, until you " "have found the root unwrapped function." msgstr "" #: howto/annotations.rst:149 msgid "" "If ``o`` is a callable (but not a class), use ``o.__globals__`` as the " "globals when calling :func:`eval`." msgstr "" #: howto/annotations.rst:152 msgid "" "However, not all string values used as annotations can be successfully " "turned into Python values by :func:`eval`. String values could theoretically " "contain any valid string, and in practice there are valid use cases for type " "hints that require annotating with string values that specifically *can't* " "be evaluated. For example:" msgstr "" #: howto/annotations.rst:159 msgid "" ":pep:`604` union types using `|`, before support for this was added to " "Python 3.10." msgstr "" #: howto/annotations.rst:161 msgid "" "Definitions that aren't needed at runtime, only imported when :const:`typing." "TYPE_CHECKING` is true." msgstr "" #: howto/annotations.rst:164 msgid "" "If :func:`eval` attempts to evaluate such values, it will fail and raise an " "exception. So, when designing a library API that works with annotations, " "it's recommended to only attempt to evaluate string values when explicitly " "requested to by the caller." msgstr "" #: howto/annotations.rst:172 msgid "Best Practices For ``__annotations__`` In Any Python Version" msgstr "" #: howto/annotations.rst:174 msgid "" "You should avoid assigning to the ``__annotations__`` member of objects " "directly. Let Python manage setting ``__annotations__``." msgstr "" #: howto/annotations.rst:177 msgid "" "If you do assign directly to the ``__annotations__`` member of an object, " "you should always set it to a ``dict`` object." msgstr "" #: howto/annotations.rst:180 msgid "" "If you directly access the ``__annotations__`` member of an object, you " "should ensure that it's a dictionary before attempting to examine its " "contents." msgstr "" #: howto/annotations.rst:184 msgid "You should avoid modifying ``__annotations__`` dicts." msgstr "" #: howto/annotations.rst:186 msgid "" "You should avoid deleting the ``__annotations__`` attribute of an object." msgstr "" #: howto/annotations.rst:191 msgid "``__annotations__`` Quirks" msgstr "" #: howto/annotations.rst:193 msgid "" "In all versions of Python 3, function objects lazy-create an annotations " "dict if no annotations are defined on that object. You can delete the " "``__annotations__`` attribute using ``del fn.__annotations__``, but if you " "then access ``fn.__annotations__`` the object will create a new empty dict " "that it will store and return as its annotations. Deleting the annotations " "on a function before it has lazily created its annotations dict will throw " "an ``AttributeError``; using ``del fn.__annotations__`` twice in a row is " "guaranteed to always throw an ``AttributeError``." msgstr "" #: howto/annotations.rst:203 msgid "" "Everything in the above paragraph also applies to class and module objects " "in Python 3.10 and newer." msgstr "" #: howto/annotations.rst:206 msgid "" "In all versions of Python 3, you can set ``__annotations__`` on a function " "object to ``None``. However, subsequently accessing the annotations on that " "object using ``fn.__annotations__`` will lazy-create an empty dictionary as " "per the first paragraph of this section. This is *not* true of modules and " "classes, in any Python version; those objects permit setting " "``__annotations__`` to any Python value, and will retain whatever value is " "set." msgstr "" #: howto/annotations.rst:214 msgid "" "If Python stringizes your annotations for you (using ``from __future__ " "import annotations``), and you specify a string as an annotation, the string " "will itself be quoted. In effect the annotation is quoted *twice.* For " "example::" msgstr "" #: howto/annotations.rst:225 msgid "" "This prints ``{'a': \"'str'\"}``. This shouldn't really be considered a " "\"quirk\"; it's mentioned here simply because it might be surprising." msgstr ""