@@ -12,7 +12,7 @@ msgid ""
1212msgstr ""
1313"Project-Id-Version : Python 3.14\n "
1414"Report-Msgid-Bugs-To : \n "
15- "POT-Creation-Date : 2025-05-08 02:53-0300 \n "
15+ "POT-Creation-Date : 2025-05-16 14:19+0000 \n "
1616"PO-Revision-Date : 2025-05-08 06:04+0000\n "
1717"
Last-Translator :
Tomasz Rodzen <[email protected] >, 2025\n "
1818"Language-Team : Polish (https://app.transifex.com/python-doc/teams/5390/pl/)\n "
@@ -186,6 +186,15 @@ msgstr ""
186186msgid "Values are the result of evaluating the annotation expressions."
187187msgstr ""
188188
189+ msgid ""
190+ "Special value used to signal that an annotate function is being evaluated in "
191+ "a special environment with fake globals. When passed this value, annotate "
192+ "functions should either return the same value as for the :attr:`Format."
193+ "VALUE` format, or raise :exc:`NotImplementedError` to signal that they do "
194+ "not support execution in this environment. This format is only used "
195+ "internally and should not be passed to the functions in this module."
196+ msgstr ""
197+
189198msgid ""
190199"Values are real annotation values (as per :attr:`Format.VALUE` format) for "
191200"defined values, and :class:`ForwardRef` proxies for undefined values. Real "
@@ -202,15 +211,6 @@ msgid ""
202211"The exact values of these strings may change in future versions of Python."
203212msgstr ""
204213
205- msgid ""
206- "Special value used to signal that an annotate function is being evaluated in "
207- "a special environment with fake globals. When passed this value, annotate "
208- "functions should either return the same value as for the :attr:`Format."
209- "VALUE` format, or raise :exc:`NotImplementedError` to signal that they do "
210- "not support execution in this environment. This format is only used "
211- "internally and should not be passed to the functions in this module."
212- msgstr ""
213-
214214msgid "A proxy object for forward references in annotations."
215215msgstr ""
216216
@@ -604,3 +604,202 @@ msgid ""
604604"attribute\n"
605605" return typ"
606606msgstr ""
607+
608+ msgid "Limitations of the ``STRING`` format"
609+ msgstr ""
610+
611+ msgid ""
612+ "The :attr:`~Format.STRING` format is meant to approximate the source code of "
613+ "the annotation, but the implementation strategy used means that it is not "
614+ "always possible to recover the exact source code."
615+ msgstr ""
616+
617+ msgid ""
618+ "First, the stringifier of course cannot recover any information that is not "
619+ "present in the compiled code, including comments, whitespace, "
620+ "parenthesization, and operations that get simplified by the compiler."
621+ msgstr ""
622+
623+ msgid ""
624+ "Second, the stringifier can intercept almost all operations that involve "
625+ "names looked up in some scope, but it cannot intercept operations that "
626+ "operate fully on constants. As a corollary, this also means it is not safe "
627+ "to request the ``STRING`` format on untrusted code: Python is powerful "
628+ "enough that it is possible to achieve arbitrary code execution even with no "
629+ "access to any globals or builtins. For example:"
630+ msgstr ""
631+
632+ msgid ""
633+ ">>> def f(x: (1).__class__.__base__.__subclasses__()[-1].__init__."
634+ "__builtins__[\" print\" ](\" Hello world\" )): pass\n"
635+ "...\n"
636+ ">>> annotationlib.get_annotations(f, format=annotationlib.Format.SOURCE)\n"
637+ "Hello world\n"
638+ "{'x': 'None'}"
639+ msgstr ""
640+
641+ msgid ""
642+ "This particular example works as of the time of writing, but it relies on "
643+ "implementation details and is not guaranteed to work in the future."
644+ msgstr ""
645+
646+ msgid ""
647+ "Among the different kinds of expressions that exist in Python, as "
648+ "represented by the :mod:`ast` module, some expressions are supported, "
649+ "meaning that the ``STRING`` format can generally recover the original source "
650+ "code; others are unsupported, meaning that they may result in incorrect "
651+ "output or an error."
652+ msgstr ""
653+
654+ msgid "The following are supported (sometimes with caveats):"
655+ msgstr ""
656+
657+ msgid ":class:`ast.BinOp`"
658+ msgstr ""
659+
660+ msgid ":class:`ast.UnaryOp`"
661+ msgstr ""
662+
663+ msgid ""
664+ ":class:`ast.Invert` (``~``), :class:`ast.UAdd` (``+``), and :class:`ast."
665+ "USub` (``-``) are supported"
666+ msgstr ""
667+
668+ msgid ":class:`ast.Not` (``not``) is not supported"
669+ msgstr ""
670+
671+ msgid ":class:`ast.Dict` (except when using ``**`` unpacking)"
672+ msgstr ""
673+
674+ msgid ":class:`ast.Set`"
675+ msgstr ""
676+
677+ msgid ":class:`ast.Compare`"
678+ msgstr ""
679+
680+ msgid ":class:`ast.Eq` and :class:`ast.NotEq` are supported"
681+ msgstr ""
682+
683+ msgid ""
684+ ":class:`ast.Lt`, :class:`ast.LtE`, :class:`ast.Gt`, and :class:`ast.GtE` are "
685+ "supported, but the operand may be flipped"
686+ msgstr ""
687+
688+ msgid ""
689+ ":class:`ast.Is`, :class:`ast.IsNot`, :class:`ast.In`, and :class:`ast.NotIn` "
690+ "are not supported"
691+ msgstr ""
692+
693+ msgid ":class:`ast.Call` (except when using ``**`` unpacking)"
694+ msgstr ""
695+
696+ msgid ""
697+ ":class:`ast.Constant` (though not the exact representation of the constant; "
698+ "for example, escape sequences in strings are lost; hexadecimal numbers are "
699+ "converted to decimal)"
700+ msgstr ""
701+
702+ msgid ":class:`ast.Attribute` (assuming the value is not a constant)"
703+ msgstr ""
704+
705+ msgid ":class:`ast.Subscript` (assuming the value is not a constant)"
706+ msgstr ""
707+
708+ msgid ":class:`ast.Starred` (``*`` unpacking)"
709+ msgstr ""
710+
711+ msgid ":class:`ast.Name`"
712+ msgstr ""
713+
714+ msgid ":class:`ast.List`"
715+ msgstr ""
716+
717+ msgid ":class:`ast.Tuple`"
718+ msgstr ""
719+
720+ msgid ":class:`ast.Slice`"
721+ msgstr ""
722+
723+ msgid ""
724+ "The following are unsupported, but throw an informative error when "
725+ "encountered by the stringifier:"
726+ msgstr ""
727+
728+ msgid ""
729+ ":class:`ast.FormattedValue` (f-strings; error is not detected if conversion "
730+ "specifiers like ``!r`` are used)"
731+ msgstr ""
732+
733+ msgid ":class:`ast.JoinedStr` (f-strings)"
734+ msgstr ""
735+
736+ msgid "The following are unsupported and result in incorrect output:"
737+ msgstr ""
738+
739+ msgid ":class:`ast.BoolOp` (``and`` and ``or``)"
740+ msgstr ""
741+
742+ msgid ":class:`ast.IfExp`"
743+ msgstr ""
744+
745+ msgid ":class:`ast.Lambda`"
746+ msgstr ""
747+
748+ msgid ":class:`ast.ListComp`"
749+ msgstr ""
750+
751+ msgid ":class:`ast.SetComp`"
752+ msgstr ""
753+
754+ msgid ":class:`ast.DictComp`"
755+ msgstr ""
756+
757+ msgid ":class:`ast.GeneratorExp`"
758+ msgstr ""
759+
760+ msgid ""
761+ "The following are disallowed in annotation scopes and therefore not relevant:"
762+ msgstr ""
763+
764+ msgid ":class:`ast.NamedExpr` (``:=``)"
765+ msgstr ""
766+
767+ msgid ":class:`ast.Await`"
768+ msgstr ""
769+
770+ msgid ":class:`ast.Yield`"
771+ msgstr ""
772+
773+ msgid ":class:`ast.YieldFrom`"
774+ msgstr ""
775+
776+ msgid "Limitations of the ``FORWARDREF`` format"
777+ msgstr ""
778+
779+ msgid ""
780+ "The :attr:`~Format.FORWARDREF` format aims to produce real values as much as "
781+ "possible, with anything that cannot be resolved replaced with :class:"
782+ "`ForwardRef` objects. It is affected by broadly the same Limitations as the :"
783+ "attr:`~Format.STRING` format: annotations that perform operations on "
784+ "literals or that use unsupported expression types may raise exceptions when "
785+ "evaluated using the :attr:`~Format.FORWARDREF` format."
786+ msgstr ""
787+
788+ msgid "Below are a few examples of the behavior with unsupported expressions:"
789+ msgstr ""
790+
791+ msgid ""
792+ ">>> from annotationlib import get_annotations, Format\n"
793+ ">>> def zerodiv(x: 1 / 0): ...\n"
794+ ">>> get_annotations(zerodiv, format=Format.STRING)\n"
795+ "Traceback (most recent call last):\n"
796+ " ...\n"
797+ "ZeroDivisionError: division by zero\n"
798+ ">>> get_annotations(zerodiv, format=Format.FORWARDREF)\n"
799+ "Traceback (most recent call last):\n"
800+ " ...\n"
801+ "ZeroDivisionError: division by zero\n"
802+ ">>> def ifexp(x: 1 if y else 0): ...\n"
803+ ">>> get_annotations(ifexp, format=Format.STRING)\n"
804+ "{'x': '1'}"
805+ msgstr ""
0 commit comments