mirror of
https://github.com/evennia/evennia.git
synced 2026-03-20 06:46:31 +01:00
3922 lines
No EOL
456 KiB
HTML
3922 lines
No EOL
456 KiB
HTML
|
|
<!DOCTYPE html>
|
|
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>typing — Evennia latest documentation</title>
|
|
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
|
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
|
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d75fae25" />
|
|
<link rel="stylesheet" type="text/css" href="../_static/nature.css?v=245aff17" />
|
|
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
|
<script src="../_static/documentation_options.js?v=c6e86fd7"></script>
|
|
<script src="../_static/doctools.js?v=9bcbadda"></script>
|
|
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
|
<link rel="index" title="Index" href="../genindex.html" />
|
|
<link rel="search" title="Search" href="../search.html" />
|
|
</head><body>
|
|
|
|
|
|
|
|
|
|
<div class="related" role="navigation" aria-label="related navigation">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../genindex.html" title="General Index"
|
|
accesskey="I">index</a></li>
|
|
<li class="right" >
|
|
<a href="../py-modindex.html" title="Python Module Index"
|
|
>modules</a> |</li>
|
|
<li class="nav-item nav-item-0"><a href="../index.html">Evennia latest</a> »</li>
|
|
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Module code</a> »</li>
|
|
<li class="nav-item nav-item-this"><a href="">typing</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="document">
|
|
|
|
<div class="documentwrapper">
|
|
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
|
<div class="sphinxsidebarwrapper">
|
|
<search id="searchbox" style="display: none" role="search">
|
|
<h3 id="searchlabel">Quick search</h3>
|
|
<div class="searchformwrapper">
|
|
<form class="search" action="../search.html" method="get">
|
|
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
|
<input type="submit" value="Go" />
|
|
</form>
|
|
</div>
|
|
</search>
|
|
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Links</h3>
|
|
<ul>
|
|
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
|
|
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
|
|
<li><a href="https://github.com/evennia/evennia">Github</a> </li>
|
|
<li><a href="http://games.evennia.com">Game Index</a> </li>
|
|
<li>
|
|
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
|
|
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
|
|
<a href="https://evennia.blogspot.com/">Blog</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="bodywrapper">
|
|
<div class="body" role="main">
|
|
|
|
<h1>Source code for typing</h1><div class="highlight"><pre>
|
|
<span></span><span class="sd">"""</span>
|
|
<span class="sd">The typing module: Support for gradual typing as defined by PEP 484 and subsequent PEPs.</span>
|
|
|
|
<span class="sd">Among other things, the module includes the following:</span>
|
|
<span class="sd">* Generic, Protocol, and internal machinery to support generic aliases.</span>
|
|
<span class="sd"> All subscripted types like X[int], Union[int, str] are generic aliases.</span>
|
|
<span class="sd">* Various "special forms" that have unique meanings in type annotations:</span>
|
|
<span class="sd"> NoReturn, Never, ClassVar, Self, Concatenate, Unpack, and others.</span>
|
|
<span class="sd">* Classes whose instances can be type arguments to generic classes and functions:</span>
|
|
<span class="sd"> TypeVar, ParamSpec, TypeVarTuple.</span>
|
|
<span class="sd">* Public helper functions: get_type_hints, overload, cast, final, and others.</span>
|
|
<span class="sd">* Several protocols to support duck-typing:</span>
|
|
<span class="sd"> SupportsFloat, SupportsIndex, SupportsAbs, and others.</span>
|
|
<span class="sd">* Special types: NewType, NamedTuple, TypedDict.</span>
|
|
<span class="sd">* Deprecated aliases for builtin types and collections.abc ABCs.</span>
|
|
|
|
<span class="sd">Any name not present in __all__ is an implementation detail</span>
|
|
<span class="sd">that may be changed without notice. Use at your own risk!</span>
|
|
<span class="sd">"""</span>
|
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">abc</span><span class="w"> </span><span class="kn">import</span> <span class="n">abstractmethod</span><span class="p">,</span> <span class="n">ABCMeta</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">collections</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">collections</span><span class="w"> </span><span class="kn">import</span> <span class="n">defaultdict</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">collections.abc</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">copyreg</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">functools</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">operator</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">sys</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">types</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">types</span><span class="w"> </span><span class="kn">import</span> <span class="n">WrapperDescriptorType</span><span class="p">,</span> <span class="n">MethodWrapperType</span><span class="p">,</span> <span class="n">MethodDescriptorType</span><span class="p">,</span> <span class="n">GenericAlias</span>
|
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">_typing</span><span class="w"> </span><span class="kn">import</span> <span class="p">(</span>
|
|
<span class="n">_idfunc</span><span class="p">,</span>
|
|
<span class="n">TypeVar</span><span class="p">,</span>
|
|
<span class="n">ParamSpec</span><span class="p">,</span>
|
|
<span class="n">TypeVarTuple</span><span class="p">,</span>
|
|
<span class="n">ParamSpecArgs</span><span class="p">,</span>
|
|
<span class="n">ParamSpecKwargs</span><span class="p">,</span>
|
|
<span class="n">TypeAliasType</span><span class="p">,</span>
|
|
<span class="n">Generic</span><span class="p">,</span>
|
|
<span class="n">NoDefault</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># Please keep __all__ alphabetized within each category.</span>
|
|
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="c1"># Super-special typing primitives.</span>
|
|
<span class="s1">'Annotated'</span><span class="p">,</span>
|
|
<span class="s1">'Any'</span><span class="p">,</span>
|
|
<span class="s1">'Callable'</span><span class="p">,</span>
|
|
<span class="s1">'ClassVar'</span><span class="p">,</span>
|
|
<span class="s1">'Concatenate'</span><span class="p">,</span>
|
|
<span class="s1">'Final'</span><span class="p">,</span>
|
|
<span class="s1">'ForwardRef'</span><span class="p">,</span>
|
|
<span class="s1">'Generic'</span><span class="p">,</span>
|
|
<span class="s1">'Literal'</span><span class="p">,</span>
|
|
<span class="s1">'Optional'</span><span class="p">,</span>
|
|
<span class="s1">'ParamSpec'</span><span class="p">,</span>
|
|
<span class="s1">'Protocol'</span><span class="p">,</span>
|
|
<span class="s1">'Tuple'</span><span class="p">,</span>
|
|
<span class="s1">'Type'</span><span class="p">,</span>
|
|
<span class="s1">'TypeVar'</span><span class="p">,</span>
|
|
<span class="s1">'TypeVarTuple'</span><span class="p">,</span>
|
|
<span class="s1">'Union'</span><span class="p">,</span>
|
|
|
|
<span class="c1"># ABCs (from collections.abc).</span>
|
|
<span class="s1">'AbstractSet'</span><span class="p">,</span> <span class="c1"># collections.abc.Set.</span>
|
|
<span class="s1">'ByteString'</span><span class="p">,</span>
|
|
<span class="s1">'Container'</span><span class="p">,</span>
|
|
<span class="s1">'ContextManager'</span><span class="p">,</span>
|
|
<span class="s1">'Hashable'</span><span class="p">,</span>
|
|
<span class="s1">'ItemsView'</span><span class="p">,</span>
|
|
<span class="s1">'Iterable'</span><span class="p">,</span>
|
|
<span class="s1">'Iterator'</span><span class="p">,</span>
|
|
<span class="s1">'KeysView'</span><span class="p">,</span>
|
|
<span class="s1">'Mapping'</span><span class="p">,</span>
|
|
<span class="s1">'MappingView'</span><span class="p">,</span>
|
|
<span class="s1">'MutableMapping'</span><span class="p">,</span>
|
|
<span class="s1">'MutableSequence'</span><span class="p">,</span>
|
|
<span class="s1">'MutableSet'</span><span class="p">,</span>
|
|
<span class="s1">'Sequence'</span><span class="p">,</span>
|
|
<span class="s1">'Sized'</span><span class="p">,</span>
|
|
<span class="s1">'ValuesView'</span><span class="p">,</span>
|
|
<span class="s1">'Awaitable'</span><span class="p">,</span>
|
|
<span class="s1">'AsyncIterator'</span><span class="p">,</span>
|
|
<span class="s1">'AsyncIterable'</span><span class="p">,</span>
|
|
<span class="s1">'Coroutine'</span><span class="p">,</span>
|
|
<span class="s1">'Collection'</span><span class="p">,</span>
|
|
<span class="s1">'AsyncGenerator'</span><span class="p">,</span>
|
|
<span class="s1">'AsyncContextManager'</span><span class="p">,</span>
|
|
|
|
<span class="c1"># Structural checks, a.k.a. protocols.</span>
|
|
<span class="s1">'Reversible'</span><span class="p">,</span>
|
|
<span class="s1">'SupportsAbs'</span><span class="p">,</span>
|
|
<span class="s1">'SupportsBytes'</span><span class="p">,</span>
|
|
<span class="s1">'SupportsComplex'</span><span class="p">,</span>
|
|
<span class="s1">'SupportsFloat'</span><span class="p">,</span>
|
|
<span class="s1">'SupportsIndex'</span><span class="p">,</span>
|
|
<span class="s1">'SupportsInt'</span><span class="p">,</span>
|
|
<span class="s1">'SupportsRound'</span><span class="p">,</span>
|
|
|
|
<span class="c1"># Concrete collection types.</span>
|
|
<span class="s1">'ChainMap'</span><span class="p">,</span>
|
|
<span class="s1">'Counter'</span><span class="p">,</span>
|
|
<span class="s1">'Deque'</span><span class="p">,</span>
|
|
<span class="s1">'Dict'</span><span class="p">,</span>
|
|
<span class="s1">'DefaultDict'</span><span class="p">,</span>
|
|
<span class="s1">'List'</span><span class="p">,</span>
|
|
<span class="s1">'OrderedDict'</span><span class="p">,</span>
|
|
<span class="s1">'Set'</span><span class="p">,</span>
|
|
<span class="s1">'FrozenSet'</span><span class="p">,</span>
|
|
<span class="s1">'NamedTuple'</span><span class="p">,</span> <span class="c1"># Not really a type.</span>
|
|
<span class="s1">'TypedDict'</span><span class="p">,</span> <span class="c1"># Not really a type.</span>
|
|
<span class="s1">'Generator'</span><span class="p">,</span>
|
|
|
|
<span class="c1"># Other concrete types.</span>
|
|
<span class="s1">'BinaryIO'</span><span class="p">,</span>
|
|
<span class="s1">'IO'</span><span class="p">,</span>
|
|
<span class="s1">'Match'</span><span class="p">,</span>
|
|
<span class="s1">'Pattern'</span><span class="p">,</span>
|
|
<span class="s1">'TextIO'</span><span class="p">,</span>
|
|
|
|
<span class="c1"># One-off things.</span>
|
|
<span class="s1">'AnyStr'</span><span class="p">,</span>
|
|
<span class="s1">'assert_type'</span><span class="p">,</span>
|
|
<span class="s1">'assert_never'</span><span class="p">,</span>
|
|
<span class="s1">'cast'</span><span class="p">,</span>
|
|
<span class="s1">'clear_overloads'</span><span class="p">,</span>
|
|
<span class="s1">'dataclass_transform'</span><span class="p">,</span>
|
|
<span class="s1">'final'</span><span class="p">,</span>
|
|
<span class="s1">'get_args'</span><span class="p">,</span>
|
|
<span class="s1">'get_origin'</span><span class="p">,</span>
|
|
<span class="s1">'get_overloads'</span><span class="p">,</span>
|
|
<span class="s1">'get_protocol_members'</span><span class="p">,</span>
|
|
<span class="s1">'get_type_hints'</span><span class="p">,</span>
|
|
<span class="s1">'is_protocol'</span><span class="p">,</span>
|
|
<span class="s1">'is_typeddict'</span><span class="p">,</span>
|
|
<span class="s1">'LiteralString'</span><span class="p">,</span>
|
|
<span class="s1">'Never'</span><span class="p">,</span>
|
|
<span class="s1">'NewType'</span><span class="p">,</span>
|
|
<span class="s1">'no_type_check'</span><span class="p">,</span>
|
|
<span class="s1">'no_type_check_decorator'</span><span class="p">,</span>
|
|
<span class="s1">'NoDefault'</span><span class="p">,</span>
|
|
<span class="s1">'NoReturn'</span><span class="p">,</span>
|
|
<span class="s1">'NotRequired'</span><span class="p">,</span>
|
|
<span class="s1">'overload'</span><span class="p">,</span>
|
|
<span class="s1">'override'</span><span class="p">,</span>
|
|
<span class="s1">'ParamSpecArgs'</span><span class="p">,</span>
|
|
<span class="s1">'ParamSpecKwargs'</span><span class="p">,</span>
|
|
<span class="s1">'ReadOnly'</span><span class="p">,</span>
|
|
<span class="s1">'Required'</span><span class="p">,</span>
|
|
<span class="s1">'reveal_type'</span><span class="p">,</span>
|
|
<span class="s1">'runtime_checkable'</span><span class="p">,</span>
|
|
<span class="s1">'Self'</span><span class="p">,</span>
|
|
<span class="s1">'Text'</span><span class="p">,</span>
|
|
<span class="s1">'TYPE_CHECKING'</span><span class="p">,</span>
|
|
<span class="s1">'TypeAlias'</span><span class="p">,</span>
|
|
<span class="s1">'TypeGuard'</span><span class="p">,</span>
|
|
<span class="s1">'TypeIs'</span><span class="p">,</span>
|
|
<span class="s1">'TypeAliasType'</span><span class="p">,</span>
|
|
<span class="s1">'Unpack'</span><span class="p">,</span>
|
|
<span class="p">]</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_type_convert</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">allow_special_forms</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""For converting None to type(None), and strings to ForwardRef."""</span>
|
|
<span class="k">if</span> <span class="n">arg</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="nb">type</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">ForwardRef</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="n">module</span><span class="p">,</span> <span class="n">is_class</span><span class="o">=</span><span class="n">allow_special_forms</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">arg</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_type_check</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">is_argument</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">allow_special_forms</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Check that the argument is a type, and return it (internal helper).</span>
|
|
|
|
<span class="sd"> As a special case, accept None and return type(None) instead. Also wrap strings</span>
|
|
<span class="sd"> into ForwardRef instances. Consider several corner cases, for example plain</span>
|
|
<span class="sd"> special forms like Union are not valid, while Union[int, str] is OK, etc.</span>
|
|
<span class="sd"> The msg argument is a human-readable error message, e.g.::</span>
|
|
|
|
<span class="sd"> "Union[arg, ...]: arg should be a type."</span>
|
|
|
|
<span class="sd"> We append the repr() of the actual value (truncated to 100 chars).</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">invalid_generic_forms</span> <span class="o">=</span> <span class="p">(</span><span class="n">Generic</span><span class="p">,</span> <span class="n">Protocol</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">allow_special_forms</span><span class="p">:</span>
|
|
<span class="n">invalid_generic_forms</span> <span class="o">+=</span> <span class="p">(</span><span class="n">ClassVar</span><span class="p">,)</span>
|
|
<span class="k">if</span> <span class="n">is_argument</span><span class="p">:</span>
|
|
<span class="n">invalid_generic_forms</span> <span class="o">+=</span> <span class="p">(</span><span class="n">Final</span><span class="p">,)</span>
|
|
|
|
<span class="n">arg</span> <span class="o">=</span> <span class="n">_type_convert</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="n">module</span><span class="p">,</span> <span class="n">allow_special_forms</span><span class="o">=</span><span class="n">allow_special_forms</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">_GenericAlias</span><span class="p">)</span> <span class="ow">and</span>
|
|
<span class="n">arg</span><span class="o">.</span><span class="n">__origin__</span> <span class="ow">in</span> <span class="n">invalid_generic_forms</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">arg</span><span class="si">}</span><span class="s2"> is not valid as type argument"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">arg</span> <span class="ow">in</span> <span class="p">(</span><span class="n">Any</span><span class="p">,</span> <span class="n">LiteralString</span><span class="p">,</span> <span class="n">NoReturn</span><span class="p">,</span> <span class="n">Never</span><span class="p">,</span> <span class="n">Self</span><span class="p">,</span> <span class="n">TypeAlias</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">arg</span>
|
|
<span class="k">if</span> <span class="n">allow_special_forms</span> <span class="ow">and</span> <span class="n">arg</span> <span class="ow">in</span> <span class="p">(</span><span class="n">ClassVar</span><span class="p">,</span> <span class="n">Final</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">arg</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">_SpecialForm</span><span class="p">)</span> <span class="ow">or</span> <span class="n">arg</span> <span class="ow">in</span> <span class="p">(</span><span class="n">Generic</span><span class="p">,</span> <span class="n">Protocol</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Plain </span><span class="si">{</span><span class="n">arg</span><span class="si">}</span><span class="s2"> is not valid as type argument"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">tuple</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">msg</span><span class="si">}</span><span class="s2"> Got </span><span class="si">{</span><span class="n">arg</span><span class="si">!r:</span><span class="s2">.100</span><span class="si">}</span><span class="s2">."</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">arg</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_is_param_expr</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">arg</span> <span class="ow">is</span> <span class="o">...</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span>
|
|
<span class="p">(</span><span class="nb">tuple</span><span class="p">,</span> <span class="nb">list</span><span class="p">,</span> <span class="n">ParamSpec</span><span class="p">,</span> <span class="n">_ConcatenateGenericAlias</span><span class="p">))</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_should_unflatten_callable_args</span><span class="p">(</span><span class="n">typ</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Internal helper for munging collections.abc.Callable's __args__.</span>
|
|
|
|
<span class="sd"> The canonical representation for a Callable's __args__ flattens the</span>
|
|
<span class="sd"> argument types, see https://github.com/python/cpython/issues/86361.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> >>> import collections.abc</span>
|
|
<span class="sd"> >>> P = ParamSpec('P')</span>
|
|
<span class="sd"> >>> collections.abc.Callable[[int, int], str].__args__ == (int, int, str)</span>
|
|
<span class="sd"> True</span>
|
|
<span class="sd"> >>> collections.abc.Callable[P, str].__args__ == (P, str)</span>
|
|
<span class="sd"> True</span>
|
|
|
|
<span class="sd"> As a result, if we need to reconstruct the Callable from its __args__,</span>
|
|
<span class="sd"> we need to unflatten it.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="n">typ</span><span class="o">.</span><span class="n">__origin__</span> <span class="ow">is</span> <span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Callable</span>
|
|
<span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">_is_param_expr</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_type_repr</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return the repr() of an object, special-casing types (internal helper).</span>
|
|
|
|
<span class="sd"> If obj is a type, we return a shorter version than the default</span>
|
|
<span class="sd"> type.__repr__, based on the module and qualified name, which is</span>
|
|
<span class="sd"> typically enough to uniquely identify a type. For everything</span>
|
|
<span class="sd"> else, we fall back on repr(obj).</span>
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># When changing this function, don't forget about</span>
|
|
<span class="c1"># `_collections_abc._type_repr`, which does the same thing</span>
|
|
<span class="c1"># and must be consistent with this one.</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__module__</span> <span class="o">==</span> <span class="s1">'builtins'</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__qualname__</span>
|
|
<span class="k">return</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">obj</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s1">.</span><span class="si">{</span><span class="n">obj</span><span class="o">.</span><span class="vm">__qualname__</span><span class="si">}</span><span class="s1">'</span>
|
|
<span class="k">if</span> <span class="n">obj</span> <span class="ow">is</span> <span class="o">...</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="s1">'...'</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">FunctionType</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="c1"># Special case for `repr` of types with `ParamSpec`:</span>
|
|
<span class="k">return</span> <span class="s1">'['</span> <span class="o">+</span> <span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">_type_repr</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">obj</span><span class="p">)</span> <span class="o">+</span> <span class="s1">']'</span>
|
|
<span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_collect_type_parameters</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">enforce_default_ordering</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Collect all type parameters in args</span>
|
|
<span class="sd"> in order of first appearance (lexicographic order).</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> >>> P = ParamSpec('P')</span>
|
|
<span class="sd"> >>> T = TypeVar('T')</span>
|
|
<span class="sd"> >>> _collect_type_parameters((T, Callable[P, T]))</span>
|
|
<span class="sd"> (~T, ~P)</span>
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># required type parameter cannot appear after parameter with default</span>
|
|
<span class="n">default_encountered</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="c1"># or after TypeVarTuple</span>
|
|
<span class="n">type_var_tuple_encountered</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">args</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="c1"># We don't want __parameters__ descriptor of a bare Python class.</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="c1"># `t` might be a tuple, when `ParamSpec` is substituted with</span>
|
|
<span class="c1"># `[T, int]`, or `[int, *Ts]`, etc.</span>
|
|
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">t</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">collected</span> <span class="ow">in</span> <span class="n">_collect_type_parameters</span><span class="p">([</span><span class="n">x</span><span class="p">]):</span>
|
|
<span class="k">if</span> <span class="n">collected</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">parameters</span><span class="p">:</span>
|
|
<span class="n">parameters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">collected</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="s1">'__typing_subst__'</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">t</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">parameters</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">enforce_default_ordering</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">type_var_tuple_encountered</span> <span class="ow">and</span> <span class="n">t</span><span class="o">.</span><span class="n">has_default</span><span class="p">():</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Type parameter with a default'</span>
|
|
<span class="s1">' follows TypeVarTuple'</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">has_default</span><span class="p">():</span>
|
|
<span class="n">default_encountered</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">elif</span> <span class="n">default_encountered</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'Type parameter </span><span class="si">{</span><span class="n">t</span><span class="si">!r}</span><span class="s1"> without a default'</span>
|
|
<span class="s1">' follows type parameter with a default'</span><span class="p">)</span>
|
|
|
|
<span class="n">parameters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">_is_unpacked_typevartuple</span><span class="p">(</span><span class="n">t</span><span class="p">):</span>
|
|
<span class="n">type_var_tuple_encountered</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="s1">'__parameters__'</span><span class="p">,</span> <span class="p">()):</span>
|
|
<span class="k">if</span> <span class="n">x</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">parameters</span><span class="p">:</span>
|
|
<span class="n">parameters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">parameters</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_check_generic_specialization</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">arguments</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Check correct count for parameters of a generic cls (internal helper).</span>
|
|
|
|
<span class="sd"> This gives a nice error message in case of count mismatch.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">expected_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">__parameters__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">expected_len</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">cls</span><span class="si">}</span><span class="s2"> is not a generic class"</span><span class="p">)</span>
|
|
<span class="n">actual_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">arguments</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">actual_len</span> <span class="o">!=</span> <span class="n">expected_len</span><span class="p">:</span>
|
|
<span class="c1"># deal with defaults</span>
|
|
<span class="k">if</span> <span class="n">actual_len</span> <span class="o"><</span> <span class="n">expected_len</span><span class="p">:</span>
|
|
<span class="c1"># If the parameter at index `actual_len` in the parameters list</span>
|
|
<span class="c1"># has a default, then all parameters after it must also have</span>
|
|
<span class="c1"># one, because we validated as much in _collect_type_parameters().</span>
|
|
<span class="c1"># That means that no error needs to be raised here, despite</span>
|
|
<span class="c1"># the number of arguments being passed not matching the number</span>
|
|
<span class="c1"># of parameters: all parameters that aren't explicitly</span>
|
|
<span class="c1"># specialized in this call are parameters with default values.</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__parameters__</span><span class="p">[</span><span class="n">actual_len</span><span class="p">]</span><span class="o">.</span><span class="n">has_default</span><span class="p">():</span>
|
|
<span class="k">return</span>
|
|
|
|
<span class="n">expected_len</span> <span class="o">-=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">has_default</span><span class="p">()</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__parameters__</span><span class="p">)</span>
|
|
<span class="n">expect_val</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"at least </span><span class="si">{</span><span class="n">expected_len</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">expect_val</span> <span class="o">=</span> <span class="n">expected_len</span>
|
|
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Too </span><span class="si">{</span><span class="s1">'many'</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">actual_len</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">expected_len</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="s1">'few'</span><span class="si">}</span><span class="s2"> arguments"</span>
|
|
<span class="sa">f</span><span class="s2">" for </span><span class="si">{</span><span class="bp">cls</span><span class="si">}</span><span class="s2">; actual </span><span class="si">{</span><span class="n">actual_len</span><span class="si">}</span><span class="s2">, expected </span><span class="si">{</span><span class="n">expect_val</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_unpack_args</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
|
|
<span class="n">newargs</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">args</span><span class="p">:</span>
|
|
<span class="n">subargs</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="s1">'__typing_unpacked_tuple_args__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">subargs</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span><span class="n">subargs</span> <span class="ow">and</span> <span class="n">subargs</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="ow">is</span> <span class="o">...</span><span class="p">):</span>
|
|
<span class="n">newargs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">subargs</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">newargs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">newargs</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_deduplicate</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">unhashable_fallback</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="c1"># Weed out strict duplicates, preserving the first of each occurrence.</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="nb">dict</span><span class="o">.</span><span class="n">fromkeys</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">unhashable_fallback</span><span class="p">:</span>
|
|
<span class="k">raise</span>
|
|
<span class="c1"># Happens for cases like `Annotated[dict, {'x': IntValidator()}]`</span>
|
|
<span class="k">return</span> <span class="n">_deduplicate_unhashable</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_deduplicate_unhashable</span><span class="p">(</span><span class="n">unhashable_params</span><span class="p">):</span>
|
|
<span class="n">new_unhashable</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">unhashable_params</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">t</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">new_unhashable</span><span class="p">:</span>
|
|
<span class="n">new_unhashable</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">new_unhashable</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_compare_args_orderless</span><span class="p">(</span><span class="n">first_args</span><span class="p">,</span> <span class="n">second_args</span><span class="p">):</span>
|
|
<span class="n">first_unhashable</span> <span class="o">=</span> <span class="n">_deduplicate_unhashable</span><span class="p">(</span><span class="n">first_args</span><span class="p">)</span>
|
|
<span class="n">second_unhashable</span> <span class="o">=</span> <span class="n">_deduplicate_unhashable</span><span class="p">(</span><span class="n">second_args</span><span class="p">)</span>
|
|
<span class="n">t</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">second_unhashable</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">first_unhashable</span><span class="p">:</span>
|
|
<span class="n">t</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
<span class="k">return</span> <span class="ow">not</span> <span class="n">t</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_remove_dups_flatten</span><span class="p">(</span><span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Internal helper for Union creation and substitution.</span>
|
|
|
|
<span class="sd"> Flatten Unions among parameters, then remove duplicates.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># Flatten out Union[Union[...], ...].</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">parameters</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="p">(</span><span class="n">_UnionGenericAlias</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">UnionType</span><span class="p">)):</span>
|
|
<span class="n">params</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">params</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_deduplicate</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="n">unhashable_fallback</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_flatten_literal_params</span><span class="p">(</span><span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Internal helper for Literal creation: flatten Literals among parameters."""</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">parameters</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">_LiteralGenericAlias</span><span class="p">):</span>
|
|
<span class="n">params</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">params</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
|
|
|
|
|
|
<span class="n">_cleanups</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">_caches</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_tp_cache</span><span class="p">(</span><span class="n">func</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">typed</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Internal wrapper caching __getitem__ of generic types.</span>
|
|
|
|
<span class="sd"> For non-hashable arguments, the original function is used as a fallback.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">decorator</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="c1"># The callback 'inner' references the newly created lru_cache</span>
|
|
<span class="c1"># indirectly by performing a lookup in the global '_caches' dictionary.</span>
|
|
<span class="c1"># This breaks a reference that can be problematic when combined with</span>
|
|
<span class="c1"># C API extensions that leak references to types. See GH-98253.</span>
|
|
|
|
<span class="n">cache</span> <span class="o">=</span> <span class="n">functools</span><span class="o">.</span><span class="n">lru_cache</span><span class="p">(</span><span class="n">typed</span><span class="o">=</span><span class="n">typed</span><span class="p">)(</span><span class="n">func</span><span class="p">)</span>
|
|
<span class="n">_caches</span><span class="p">[</span><span class="n">func</span><span class="p">]</span> <span class="o">=</span> <span class="n">cache</span>
|
|
<span class="n">_cleanups</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">cache</span><span class="o">.</span><span class="n">cache_clear</span><span class="p">)</span>
|
|
<span class="k">del</span> <span class="n">cache</span>
|
|
|
|
<span class="nd">@functools</span><span class="o">.</span><span class="n">wraps</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">inner</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">_caches</span><span class="p">[</span><span class="n">func</span><span class="p">](</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="k">pass</span> <span class="c1"># All real errors (not unhashable args) are raised below.</span>
|
|
<span class="k">return</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">inner</span>
|
|
|
|
<span class="k">if</span> <span class="n">func</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">decorator</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">decorator</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_deprecation_warning_for_no_type_params_passed</span><span class="p">(</span><span class="n">funcname</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">warnings</span>
|
|
|
|
<span class="n">depr_message</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Failing to pass a value to the 'type_params' parameter "</span>
|
|
<span class="sa">f</span><span class="s2">"of </span><span class="si">{</span><span class="n">funcname</span><span class="si">!r}</span><span class="s2"> is deprecated, as it leads to incorrect behaviour "</span>
|
|
<span class="sa">f</span><span class="s2">"when calling </span><span class="si">{</span><span class="n">funcname</span><span class="si">}</span><span class="s2"> on a stringified annotation "</span>
|
|
<span class="sa">f</span><span class="s2">"that references a PEP 695 type parameter. "</span>
|
|
<span class="sa">f</span><span class="s2">"It will be disallowed in Python 3.15."</span>
|
|
<span class="p">)</span>
|
|
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">depr_message</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="ne">DeprecationWarning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_Sentinel</span><span class="p">:</span>
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="s1">'<sentinel>'</span>
|
|
|
|
|
|
<span class="n">_sentinel</span> <span class="o">=</span> <span class="n">_Sentinel</span><span class="p">()</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_eval_type</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">globalns</span><span class="p">,</span> <span class="n">localns</span><span class="p">,</span> <span class="n">type_params</span><span class="o">=</span><span class="n">_sentinel</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">recursive_guard</span><span class="o">=</span><span class="nb">frozenset</span><span class="p">()):</span>
|
|
<span class="w"> </span><span class="sd">"""Evaluate all forward references in the given type t.</span>
|
|
|
|
<span class="sd"> For use of globalns and localns see the docstring for get_type_hints().</span>
|
|
<span class="sd"> recursive_guard is used to prevent infinite recursion with a recursive</span>
|
|
<span class="sd"> ForwardRef.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">type_params</span> <span class="ow">is</span> <span class="n">_sentinel</span><span class="p">:</span>
|
|
<span class="n">_deprecation_warning_for_no_type_params_passed</span><span class="p">(</span><span class="s2">"typing._eval_type"</span><span class="p">)</span>
|
|
<span class="n">type_params</span> <span class="o">=</span> <span class="p">()</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">ForwardRef</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">t</span><span class="o">.</span><span class="n">_evaluate</span><span class="p">(</span><span class="n">globalns</span><span class="p">,</span> <span class="n">localns</span><span class="p">,</span> <span class="n">type_params</span><span class="p">,</span> <span class="n">recursive_guard</span><span class="o">=</span><span class="n">recursive_guard</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="p">(</span><span class="n">_GenericAlias</span><span class="p">,</span> <span class="n">GenericAlias</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">UnionType</span><span class="p">)):</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">GenericAlias</span><span class="p">):</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span>
|
|
<span class="n">ForwardRef</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="n">arg</span>
|
|
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">t</span><span class="o">.</span><span class="n">__args__</span>
|
|
<span class="p">)</span>
|
|
<span class="n">is_unpacked</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">__unpacked__</span>
|
|
<span class="k">if</span> <span class="n">_should_unflatten_callable_args</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
|
<span class="n">t</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">__origin__</span><span class="p">[(</span><span class="n">args</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">args</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">t</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">__origin__</span><span class="p">[</span><span class="n">args</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">is_unpacked</span><span class="p">:</span>
|
|
<span class="n">t</span> <span class="o">=</span> <span class="n">Unpack</span><span class="p">[</span><span class="n">t</span><span class="p">]</span>
|
|
|
|
<span class="n">ev_args</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span>
|
|
<span class="n">_eval_type</span><span class="p">(</span>
|
|
<span class="n">a</span><span class="p">,</span> <span class="n">globalns</span><span class="p">,</span> <span class="n">localns</span><span class="p">,</span> <span class="n">type_params</span><span class="p">,</span> <span class="n">recursive_guard</span><span class="o">=</span><span class="n">recursive_guard</span>
|
|
<span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">t</span><span class="o">.</span><span class="n">__args__</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">ev_args</span> <span class="o">==</span> <span class="n">t</span><span class="o">.</span><span class="n">__args__</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">t</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">GenericAlias</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">GenericAlias</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,</span> <span class="n">ev_args</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">UnionType</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">functools</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="n">operator</span><span class="o">.</span><span class="n">or_</span><span class="p">,</span> <span class="n">ev_args</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">t</span><span class="o">.</span><span class="n">copy_with</span><span class="p">(</span><span class="n">ev_args</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">t</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_Final</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Mixin to prohibit subclassing."""</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'__weakref__'</span><span class="p">,)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__init_subclass__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="s1">'_root'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">kwds</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Cannot subclass special typing classes"</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_NotIterable</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Mixin to prevent iteration, without being compatible with Iterable.</span>
|
|
|
|
<span class="sd"> That is, we could do::</span>
|
|
|
|
<span class="sd"> def __iter__(self): raise TypeError()</span>
|
|
|
|
<span class="sd"> But this would make users of this mixin duck type-compatible with</span>
|
|
<span class="sd"> collections.abc.Iterable - isinstance(foo, Iterable) would be True.</span>
|
|
|
|
<span class="sd"> Luckily, we can instead prevent iteration by setting __iter__ to None, which</span>
|
|
<span class="sd"> is treated specially.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
<span class="fm">__iter__</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
|
|
<span class="c1"># Internal indicator of special typing constructs.</span>
|
|
<span class="c1"># See __doc__ instance attribute for specific docs.</span>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_SpecialForm</span><span class="p">(</span><span class="n">_Final</span><span class="p">,</span> <span class="n">_NotIterable</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'_name'</span><span class="p">,</span> <span class="s1">'__doc__'</span><span class="p">,</span> <span class="s1">'_getitem'</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">getitem</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_getitem</span> <span class="o">=</span> <span class="n">getitem</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="n">getitem</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="vm">__doc__</span> <span class="o">=</span> <span class="n">getitem</span><span class="o">.</span><span class="vm">__doc__</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">item</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">item</span> <span class="ow">in</span> <span class="p">{</span><span class="s1">'__name__'</span><span class="p">,</span> <span class="s1">'__qualname__'</span><span class="p">}:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>
|
|
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__mro_entries__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Cannot subclass </span><span class="si">{</span><span class="bp">self</span><span class="si">!r}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="s1">'typing.'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Cannot instantiate </span><span class="si">{</span><span class="bp">self</span><span class="si">!r}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__or__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__ror__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__instancecheck__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2"> cannot be used with isinstance()"</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__subclasscheck__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2"> cannot be used with issubclass()"</span><span class="p">)</span>
|
|
|
|
<span class="nd">@_tp_cache</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getitem</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_TypedCacheSpecialForm</span><span class="p">(</span><span class="n">_SpecialForm</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="p">(</span><span class="n">parameters</span><span class="p">,)</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getitem</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">parameters</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_AnyMeta</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__instancecheck__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span> <span class="ow">is</span> <span class="n">Any</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"typing.Any cannot be used with isinstance()"</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__instancecheck__</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span> <span class="ow">is</span> <span class="n">Any</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="s2">"typing.Any"</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__repr__</span><span class="p">()</span> <span class="c1"># respect to subclasses</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">Any</span><span class="p">(</span><span class="n">metaclass</span><span class="o">=</span><span class="n">_AnyMeta</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Special type indicating an unconstrained type.</span>
|
|
|
|
<span class="sd"> - Any is compatible with every type.</span>
|
|
<span class="sd"> - Any assumed to have all methods.</span>
|
|
<span class="sd"> - All values assumed to be instances of Any.</span>
|
|
|
|
<span class="sd"> Note that all the above statements are true from the point of view of</span>
|
|
<span class="sd"> static type checkers. At runtime, Any should not be used with instance</span>
|
|
<span class="sd"> checks.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">cls</span> <span class="ow">is</span> <span class="n">Any</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Any cannot be instantiated"</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span>
|
|
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">NoReturn</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Special type indicating functions that never return.</span>
|
|
|
|
<span class="sd"> Example::</span>
|
|
|
|
<span class="sd"> from typing import NoReturn</span>
|
|
|
|
<span class="sd"> def stop() -> NoReturn:</span>
|
|
<span class="sd"> raise Exception('no way')</span>
|
|
|
|
<span class="sd"> NoReturn can also be used as a bottom type, a type that</span>
|
|
<span class="sd"> has no values. Starting in Python 3.11, the Never type should</span>
|
|
<span class="sd"> be used for this concept instead. Type checkers should treat the two</span>
|
|
<span class="sd"> equivalently.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2"> is not subscriptable"</span><span class="p">)</span>
|
|
|
|
<span class="c1"># This is semantically identical to NoReturn, but it is implemented</span>
|
|
<span class="c1"># separately so that type checkers can distinguish between the two</span>
|
|
<span class="c1"># if they want.</span>
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">Never</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""The bottom type, a type that has no members.</span>
|
|
|
|
<span class="sd"> This can be used to define a function that should never be</span>
|
|
<span class="sd"> called, or a function that never returns::</span>
|
|
|
|
<span class="sd"> from typing import Never</span>
|
|
|
|
<span class="sd"> def never_call_me(arg: Never) -> None:</span>
|
|
<span class="sd"> pass</span>
|
|
|
|
<span class="sd"> def int_or_str(arg: int | str) -> None:</span>
|
|
<span class="sd"> never_call_me(arg) # type checker error</span>
|
|
<span class="sd"> match arg:</span>
|
|
<span class="sd"> case int():</span>
|
|
<span class="sd"> print("It's an int")</span>
|
|
<span class="sd"> case str():</span>
|
|
<span class="sd"> print("It's a str")</span>
|
|
<span class="sd"> case _:</span>
|
|
<span class="sd"> never_call_me(arg) # OK, arg is of type Never</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2"> is not subscriptable"</span><span class="p">)</span>
|
|
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">Self</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Used to spell the type of "self" in classes.</span>
|
|
|
|
<span class="sd"> Example::</span>
|
|
|
|
<span class="sd"> from typing import Self</span>
|
|
|
|
<span class="sd"> class Foo:</span>
|
|
<span class="sd"> def return_self(self) -> Self:</span>
|
|
<span class="sd"> ...</span>
|
|
<span class="sd"> return self</span>
|
|
|
|
<span class="sd"> This is especially useful for:</span>
|
|
<span class="sd"> - classmethods that are used as alternative constructors</span>
|
|
<span class="sd"> - annotating an `__enter__` method which returns self</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2"> is not subscriptable"</span><span class="p">)</span>
|
|
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">LiteralString</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Represents an arbitrary literal string.</span>
|
|
|
|
<span class="sd"> Example::</span>
|
|
|
|
<span class="sd"> from typing import LiteralString</span>
|
|
|
|
<span class="sd"> def run_query(sql: LiteralString) -> None:</span>
|
|
<span class="sd"> ...</span>
|
|
|
|
<span class="sd"> def caller(arbitrary_string: str, literal_string: LiteralString) -> None:</span>
|
|
<span class="sd"> run_query("SELECT * FROM students") # OK</span>
|
|
<span class="sd"> run_query(literal_string) # OK</span>
|
|
<span class="sd"> run_query("SELECT * FROM " + literal_string) # OK</span>
|
|
<span class="sd"> run_query(arbitrary_string) # type checker error</span>
|
|
<span class="sd"> run_query( # type checker error</span>
|
|
<span class="sd"> f"SELECT * FROM students WHERE name = {arbitrary_string}"</span>
|
|
<span class="sd"> )</span>
|
|
|
|
<span class="sd"> Only string literals and other LiteralStrings are compatible</span>
|
|
<span class="sd"> with LiteralString. This provides a tool to help prevent</span>
|
|
<span class="sd"> security issues such as SQL injection.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2"> is not subscriptable"</span><span class="p">)</span>
|
|
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">ClassVar</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Special type construct to mark class variables.</span>
|
|
|
|
<span class="sd"> An annotation wrapped in ClassVar indicates that a given</span>
|
|
<span class="sd"> attribute is intended to be used as a class variable and</span>
|
|
<span class="sd"> should not be set on instances of that class.</span>
|
|
|
|
<span class="sd"> Usage::</span>
|
|
|
|
<span class="sd"> class Starship:</span>
|
|
<span class="sd"> stats: ClassVar[dict[str, int]] = {} # class variable</span>
|
|
<span class="sd"> damage: int = 10 # instance variable</span>
|
|
|
|
<span class="sd"> ClassVar accepts only types and cannot be further subscribed.</span>
|
|
|
|
<span class="sd"> Note that ClassVar is not a class itself, and should not</span>
|
|
<span class="sd"> be used with isinstance() or issubclass().</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">item</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s1"> accepts only single type.'</span><span class="p">,</span> <span class="n">allow_special_forms</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_GenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="p">(</span><span class="n">item</span><span class="p">,))</span>
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">Final</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Special typing construct to indicate final names to type checkers.</span>
|
|
|
|
<span class="sd"> A final name cannot be re-assigned or overridden in a subclass.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> MAX_SIZE: Final = 9000</span>
|
|
<span class="sd"> MAX_SIZE += 1 # Error reported by type checker</span>
|
|
|
|
<span class="sd"> class Connection:</span>
|
|
<span class="sd"> TIMEOUT: Final[int] = 10</span>
|
|
|
|
<span class="sd"> class FastConnector(Connection):</span>
|
|
<span class="sd"> TIMEOUT = 1 # Error reported by type checker</span>
|
|
|
|
<span class="sd"> There is no runtime checking of these properties.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">item</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s1"> accepts only single type.'</span><span class="p">,</span> <span class="n">allow_special_forms</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_GenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="p">(</span><span class="n">item</span><span class="p">,))</span>
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">Union</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Union type; Union[X, Y] means either X or Y.</span>
|
|
|
|
<span class="sd"> On Python 3.10 and higher, the | operator</span>
|
|
<span class="sd"> can also be used to denote unions;</span>
|
|
<span class="sd"> X | Y means the same thing to the type checker as Union[X, Y].</span>
|
|
|
|
<span class="sd"> To define a union, use e.g. Union[int, str]. Details:</span>
|
|
<span class="sd"> - The arguments must be types and there must be at least one.</span>
|
|
<span class="sd"> - None as an argument is a special case and is replaced by</span>
|
|
<span class="sd"> type(None).</span>
|
|
<span class="sd"> - Unions of unions are flattened, e.g.::</span>
|
|
|
|
<span class="sd"> assert Union[Union[int, str], float] == Union[int, str, float]</span>
|
|
|
|
<span class="sd"> - Unions of a single argument vanish, e.g.::</span>
|
|
|
|
<span class="sd"> assert Union[int] == int # The constructor actually returns int</span>
|
|
|
|
<span class="sd"> - Redundant arguments are skipped, e.g.::</span>
|
|
|
|
<span class="sd"> assert Union[int, str, int] == Union[int, str]</span>
|
|
|
|
<span class="sd"> - When comparing unions, the argument order is ignored, e.g.::</span>
|
|
|
|
<span class="sd"> assert Union[int, str] == Union[str, int]</span>
|
|
|
|
<span class="sd"> - You cannot subclass or instantiate a union.</span>
|
|
<span class="sd"> - You can use Optional[X] as a shorthand for Union[X, None].</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">parameters</span> <span class="o">==</span> <span class="p">():</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Cannot take a Union of no types."</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="p">(</span><span class="n">parameters</span><span class="p">,)</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s2">"Union[arg, ...]: each arg must be a type."</span>
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_type_check</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">parameters</span><span class="p">)</span>
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="n">_remove_dups_flatten</span><span class="p">(</span><span class="n">parameters</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">parameters</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">parameters</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">parameters</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span> <span class="ow">and</span> <span class="nb">type</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span> <span class="ow">in</span> <span class="n">parameters</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">_UnionGenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">"Optional"</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_UnionGenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_make_union</span><span class="p">(</span><span class="n">left</span><span class="p">,</span> <span class="n">right</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Used from the C implementation of TypeVar.</span>
|
|
|
|
<span class="sd"> TypeVar.__or__ calls this instead of returning types.UnionType</span>
|
|
<span class="sd"> because we want to allow unions between TypeVars and strings</span>
|
|
<span class="sd"> (forward references).</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="n">left</span><span class="p">,</span> <span class="n">right</span><span class="p">]</span>
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">Optional</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Optional[X] is equivalent to Union[X, None]."""</span>
|
|
<span class="n">arg</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2"> requires a single type."</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="n">arg</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="kc">None</span><span class="p">)]</span>
|
|
|
|
<span class="nd">@_TypedCacheSpecialForm</span>
|
|
<span class="nd">@_tp_cache</span><span class="p">(</span><span class="n">typed</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">Literal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Special typing form to define literal types (a.k.a. value types).</span>
|
|
|
|
<span class="sd"> This form can be used to indicate to type checkers that the corresponding</span>
|
|
<span class="sd"> variable or function parameter has a value equivalent to the provided</span>
|
|
<span class="sd"> literal (or one of several literals)::</span>
|
|
|
|
<span class="sd"> def validate_simple(data: Any) -> Literal[True]: # always returns True</span>
|
|
<span class="sd"> ...</span>
|
|
|
|
<span class="sd"> MODE = Literal['r', 'rb', 'w', 'wb']</span>
|
|
<span class="sd"> def open_helper(file: str, mode: MODE) -> str:</span>
|
|
<span class="sd"> ...</span>
|
|
|
|
<span class="sd"> open_helper('/some/path', 'r') # Passes type check</span>
|
|
<span class="sd"> open_helper('/other/path', 'typo') # Error in type checker</span>
|
|
|
|
<span class="sd"> Literal[...] cannot be subclassed. At runtime, an arbitrary value</span>
|
|
<span class="sd"> is allowed as type argument to Literal[...], but type checkers may</span>
|
|
<span class="sd"> impose restrictions.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># There is no '_type_check' call because arguments to Literal[...] are</span>
|
|
<span class="c1"># values, not types.</span>
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="n">_flatten_literal_params</span><span class="p">(</span><span class="n">parameters</span><span class="p">)</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">_deduplicate</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">_value_and_type_iter</span><span class="p">(</span><span class="n">parameters</span><span class="p">))))</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> <span class="c1"># unhashable parameters</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="k">return</span> <span class="n">_LiteralGenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">)</span>
|
|
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">TypeAlias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Special form for marking type aliases.</span>
|
|
|
|
<span class="sd"> Use TypeAlias to indicate that an assignment should</span>
|
|
<span class="sd"> be recognized as a proper type alias definition by type</span>
|
|
<span class="sd"> checkers.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> Predicate: TypeAlias = Callable[..., bool]</span>
|
|
|
|
<span class="sd"> It's invalid when used anywhere except as in the example above.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2"> is not subscriptable"</span><span class="p">)</span>
|
|
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">Concatenate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Special form for annotating higher-order functions.</span>
|
|
|
|
<span class="sd"> ``Concatenate`` can be used in conjunction with ``ParamSpec`` and</span>
|
|
<span class="sd"> ``Callable`` to represent a higher-order function which adds, removes or</span>
|
|
<span class="sd"> transforms the parameters of a callable.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> Callable[Concatenate[int, P], int]</span>
|
|
|
|
<span class="sd"> See PEP 612 for detailed information.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">parameters</span> <span class="o">==</span> <span class="p">():</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Cannot take a Concatenate of no types."</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="p">(</span><span class="n">parameters</span><span class="p">,)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">parameters</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="ow">is</span> <span class="o">...</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parameters</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">ParamSpec</span><span class="p">)):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"The last parameter to Concatenate should be a "</span>
|
|
<span class="s2">"ParamSpec variable or ellipsis."</span><span class="p">)</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s2">"Concatenate[arg, ...]: each arg must be a type."</span>
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">_type_check</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">parameters</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]),</span> <span class="n">parameters</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
|
|
<span class="k">return</span> <span class="n">_ConcatenateGenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">)</span>
|
|
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">TypeGuard</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Special typing construct for marking user-defined type predicate functions.</span>
|
|
|
|
<span class="sd"> ``TypeGuard`` can be used to annotate the return type of a user-defined</span>
|
|
<span class="sd"> type predicate function. ``TypeGuard`` only accepts a single type argument.</span>
|
|
<span class="sd"> At runtime, functions marked this way should return a boolean.</span>
|
|
|
|
<span class="sd"> ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static</span>
|
|
<span class="sd"> type checkers to determine a more precise type of an expression within a</span>
|
|
<span class="sd"> program's code flow. Usually type narrowing is done by analyzing</span>
|
|
<span class="sd"> conditional code flow and applying the narrowing to a block of code. The</span>
|
|
<span class="sd"> conditional expression here is sometimes referred to as a "type predicate".</span>
|
|
|
|
<span class="sd"> Sometimes it would be convenient to use a user-defined boolean function</span>
|
|
<span class="sd"> as a type predicate. Such a function should use ``TypeGuard[...]`` or</span>
|
|
<span class="sd"> ``TypeIs[...]`` as its return type to alert static type checkers to</span>
|
|
<span class="sd"> this intention. ``TypeGuard`` should be used over ``TypeIs`` when narrowing</span>
|
|
<span class="sd"> from an incompatible type (e.g., ``list[object]`` to ``list[int]``) or when</span>
|
|
<span class="sd"> the function does not return ``True`` for all instances of the narrowed type.</span>
|
|
|
|
<span class="sd"> Using ``-> TypeGuard[NarrowedType]`` tells the static type checker that</span>
|
|
<span class="sd"> for a given function:</span>
|
|
|
|
<span class="sd"> 1. The return value is a boolean.</span>
|
|
<span class="sd"> 2. If the return value is ``True``, the type of its argument</span>
|
|
<span class="sd"> is ``NarrowedType``.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> def is_str_list(val: list[object]) -> TypeGuard[list[str]]:</span>
|
|
<span class="sd"> '''Determines whether all objects in the list are strings'''</span>
|
|
<span class="sd"> return all(isinstance(x, str) for x in val)</span>
|
|
|
|
<span class="sd"> def func1(val: list[object]):</span>
|
|
<span class="sd"> if is_str_list(val):</span>
|
|
<span class="sd"> # Type of ``val`` is narrowed to ``list[str]``.</span>
|
|
<span class="sd"> print(" ".join(val))</span>
|
|
<span class="sd"> else:</span>
|
|
<span class="sd"> # Type of ``val`` remains as ``list[object]``.</span>
|
|
<span class="sd"> print("Not a list of strings!")</span>
|
|
|
|
<span class="sd"> Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower</span>
|
|
<span class="sd"> form of ``TypeA`` (it can even be a wider form) and this may lead to</span>
|
|
<span class="sd"> type-unsafe results. The main reason is to allow for things like</span>
|
|
<span class="sd"> narrowing ``list[object]`` to ``list[str]`` even though the latter is not</span>
|
|
<span class="sd"> a subtype of the former, since ``list`` is invariant. The responsibility of</span>
|
|
<span class="sd"> writing type-safe type predicates is left to the user.</span>
|
|
|
|
<span class="sd"> ``TypeGuard`` also works with type variables. For more information, see</span>
|
|
<span class="sd"> PEP 647 (User-Defined Type Guards).</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">item</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s1"> accepts only single type.'</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_GenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="p">(</span><span class="n">item</span><span class="p">,))</span>
|
|
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">TypeIs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Special typing construct for marking user-defined type predicate functions.</span>
|
|
|
|
<span class="sd"> ``TypeIs`` can be used to annotate the return type of a user-defined</span>
|
|
<span class="sd"> type predicate function. ``TypeIs`` only accepts a single type argument.</span>
|
|
<span class="sd"> At runtime, functions marked this way should return a boolean and accept</span>
|
|
<span class="sd"> at least one argument.</span>
|
|
|
|
<span class="sd"> ``TypeIs`` aims to benefit *type narrowing* -- a technique used by static</span>
|
|
<span class="sd"> type checkers to determine a more precise type of an expression within a</span>
|
|
<span class="sd"> program's code flow. Usually type narrowing is done by analyzing</span>
|
|
<span class="sd"> conditional code flow and applying the narrowing to a block of code. The</span>
|
|
<span class="sd"> conditional expression here is sometimes referred to as a "type predicate".</span>
|
|
|
|
<span class="sd"> Sometimes it would be convenient to use a user-defined boolean function</span>
|
|
<span class="sd"> as a type predicate. Such a function should use ``TypeIs[...]`` or</span>
|
|
<span class="sd"> ``TypeGuard[...]`` as its return type to alert static type checkers to</span>
|
|
<span class="sd"> this intention. ``TypeIs`` usually has more intuitive behavior than</span>
|
|
<span class="sd"> ``TypeGuard``, but it cannot be used when the input and output types</span>
|
|
<span class="sd"> are incompatible (e.g., ``list[object]`` to ``list[int]``) or when the</span>
|
|
<span class="sd"> function does not return ``True`` for all instances of the narrowed type.</span>
|
|
|
|
<span class="sd"> Using ``-> TypeIs[NarrowedType]`` tells the static type checker that for</span>
|
|
<span class="sd"> a given function:</span>
|
|
|
|
<span class="sd"> 1. The return value is a boolean.</span>
|
|
<span class="sd"> 2. If the return value is ``True``, the type of its argument</span>
|
|
<span class="sd"> is the intersection of the argument's original type and</span>
|
|
<span class="sd"> ``NarrowedType``.</span>
|
|
<span class="sd"> 3. If the return value is ``False``, the type of its argument</span>
|
|
<span class="sd"> is narrowed to exclude ``NarrowedType``.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> from typing import assert_type, final, TypeIs</span>
|
|
|
|
<span class="sd"> class Parent: pass</span>
|
|
<span class="sd"> class Child(Parent): pass</span>
|
|
<span class="sd"> @final</span>
|
|
<span class="sd"> class Unrelated: pass</span>
|
|
|
|
<span class="sd"> def is_parent(val: object) -> TypeIs[Parent]:</span>
|
|
<span class="sd"> return isinstance(val, Parent)</span>
|
|
|
|
<span class="sd"> def run(arg: Child | Unrelated):</span>
|
|
<span class="sd"> if is_parent(arg):</span>
|
|
<span class="sd"> # Type of ``arg`` is narrowed to the intersection</span>
|
|
<span class="sd"> # of ``Parent`` and ``Child``, which is equivalent to</span>
|
|
<span class="sd"> # ``Child``.</span>
|
|
<span class="sd"> assert_type(arg, Child)</span>
|
|
<span class="sd"> else:</span>
|
|
<span class="sd"> # Type of ``arg`` is narrowed to exclude ``Parent``,</span>
|
|
<span class="sd"> # so only ``Unrelated`` is left.</span>
|
|
<span class="sd"> assert_type(arg, Unrelated)</span>
|
|
|
|
<span class="sd"> The type inside ``TypeIs`` must be consistent with the type of the</span>
|
|
<span class="sd"> function's argument; if it is not, static type checkers will raise</span>
|
|
<span class="sd"> an error. An incorrectly written ``TypeIs`` function can lead to</span>
|
|
<span class="sd"> unsound behavior in the type system; it is the user's responsibility</span>
|
|
<span class="sd"> to write such functions in a type-safe manner.</span>
|
|
|
|
<span class="sd"> ``TypeIs`` also works with type variables. For more information, see</span>
|
|
<span class="sd"> PEP 742 (Narrowing types with ``TypeIs``).</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">item</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s1"> accepts only single type.'</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_GenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="p">(</span><span class="n">item</span><span class="p">,))</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">ForwardRef</span><span class="p">(</span><span class="n">_Final</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Internal wrapper to hold a forward reference."""</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'__forward_arg__'</span><span class="p">,</span> <span class="s1">'__forward_code__'</span><span class="p">,</span>
|
|
<span class="s1">'__forward_evaluated__'</span><span class="p">,</span> <span class="s1">'__forward_value__'</span><span class="p">,</span>
|
|
<span class="s1">'__forward_is_argument__'</span><span class="p">,</span> <span class="s1">'__forward_is_class__'</span><span class="p">,</span>
|
|
<span class="s1">'__forward_module__'</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">,</span> <span class="n">is_argument</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">is_class</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Forward reference must be a string -- got </span><span class="si">{</span><span class="n">arg</span><span class="si">!r}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="c1"># If we do `def f(*args: *Ts)`, then we'll have `arg = '*Ts'`.</span>
|
|
<span class="c1"># Unfortunately, this isn't a valid expression on its own, so we</span>
|
|
<span class="c1"># do the unpacking manually.</span>
|
|
<span class="k">if</span> <span class="n">arg</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'*'</span><span class="p">):</span>
|
|
<span class="n">arg_to_compile</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">'(</span><span class="si">{</span><span class="n">arg</span><span class="si">}</span><span class="s1">,)[0]'</span> <span class="c1"># E.g. (*Ts,)[0] or (*tuple[int, int],)[0]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">arg_to_compile</span> <span class="o">=</span> <span class="n">arg</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">code</span> <span class="o">=</span> <span class="nb">compile</span><span class="p">(</span><span class="n">arg_to_compile</span><span class="p">,</span> <span class="s1">'<string>'</span><span class="p">,</span> <span class="s1">'eval'</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">SyntaxError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">SyntaxError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Forward reference must be an expression -- got </span><span class="si">{</span><span class="n">arg</span><span class="si">!r}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__forward_arg__</span> <span class="o">=</span> <span class="n">arg</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__forward_code__</span> <span class="o">=</span> <span class="n">code</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__forward_evaluated__</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__forward_value__</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__forward_is_argument__</span> <span class="o">=</span> <span class="n">is_argument</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__forward_is_class__</span> <span class="o">=</span> <span class="n">is_class</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__forward_module__</span> <span class="o">=</span> <span class="n">module</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_evaluate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">globalns</span><span class="p">,</span> <span class="n">localns</span><span class="p">,</span> <span class="n">type_params</span><span class="o">=</span><span class="n">_sentinel</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">recursive_guard</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">type_params</span> <span class="ow">is</span> <span class="n">_sentinel</span><span class="p">:</span>
|
|
<span class="n">_deprecation_warning_for_no_type_params_passed</span><span class="p">(</span><span class="s2">"typing.ForwardRef._evaluate"</span><span class="p">)</span>
|
|
<span class="n">type_params</span> <span class="o">=</span> <span class="p">()</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__forward_arg__</span> <span class="ow">in</span> <span class="n">recursive_guard</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">__forward_evaluated__</span> <span class="ow">or</span> <span class="n">localns</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">globalns</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">globalns</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">localns</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">globalns</span> <span class="o">=</span> <span class="n">localns</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">elif</span> <span class="n">globalns</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">globalns</span> <span class="o">=</span> <span class="n">localns</span>
|
|
<span class="k">elif</span> <span class="n">localns</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">localns</span> <span class="o">=</span> <span class="n">globalns</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__forward_module__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">globalns</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span>
|
|
<span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__forward_module__</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span> <span class="s1">'__dict__'</span><span class="p">,</span> <span class="n">globalns</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># type parameters require some special handling,</span>
|
|
<span class="c1"># as they exist in their own scope</span>
|
|
<span class="c1"># but `eval()` does not have a dedicated parameter for that scope.</span>
|
|
<span class="c1"># For classes, names in type parameter scopes should override</span>
|
|
<span class="c1"># names in the global scope (which here are called `localns`!),</span>
|
|
<span class="c1"># but should in turn be overridden by names in the class scope</span>
|
|
<span class="c1"># (which here are called `globalns`!)</span>
|
|
<span class="k">if</span> <span class="n">type_params</span><span class="p">:</span>
|
|
<span class="n">globalns</span><span class="p">,</span> <span class="n">localns</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">globalns</span><span class="p">),</span> <span class="nb">dict</span><span class="p">(</span><span class="n">localns</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">type_params</span><span class="p">:</span>
|
|
<span class="n">param_name</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">__forward_is_class__</span> <span class="ow">or</span> <span class="n">param_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">globalns</span><span class="p">:</span>
|
|
<span class="n">globalns</span><span class="p">[</span><span class="n">param_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">param</span>
|
|
<span class="n">localns</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">param_name</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
|
|
<span class="n">type_</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span>
|
|
<span class="nb">eval</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__forward_code__</span><span class="p">,</span> <span class="n">globalns</span><span class="p">,</span> <span class="n">localns</span><span class="p">),</span>
|
|
<span class="s2">"Forward references must evaluate to types."</span><span class="p">,</span>
|
|
<span class="n">is_argument</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">__forward_is_argument__</span><span class="p">,</span>
|
|
<span class="n">allow_special_forms</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">__forward_is_class__</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__forward_value__</span> <span class="o">=</span> <span class="n">_eval_type</span><span class="p">(</span>
|
|
<span class="n">type_</span><span class="p">,</span>
|
|
<span class="n">globalns</span><span class="p">,</span>
|
|
<span class="n">localns</span><span class="p">,</span>
|
|
<span class="n">type_params</span><span class="p">,</span>
|
|
<span class="n">recursive_guard</span><span class="o">=</span><span class="p">(</span><span class="n">recursive_guard</span> <span class="o">|</span> <span class="p">{</span><span class="bp">self</span><span class="o">.</span><span class="n">__forward_arg__</span><span class="p">}),</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__forward_evaluated__</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__forward_value__</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">ForwardRef</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__forward_evaluated__</span> <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">__forward_evaluated__</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__forward_arg__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">__forward_arg__</span> <span class="ow">and</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__forward_value__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">__forward_value__</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__forward_arg__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">__forward_arg__</span> <span class="ow">and</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__forward_module__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">__forward_module__</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">hash</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">__forward_arg__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">__forward_module__</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__or__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__ror__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__forward_module__</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">module_repr</span> <span class="o">=</span> <span class="s1">''</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">module_repr</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">', module=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">__forward_module__</span><span class="si">!r}</span><span class="s1">'</span>
|
|
<span class="k">return</span> <span class="sa">f</span><span class="s1">'ForwardRef(</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">__forward_arg__</span><span class="si">!r}{</span><span class="n">module_repr</span><span class="si">}</span><span class="s1">)'</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_is_unpacked_typevartuple</span><span class="p">(</span><span class="n">x</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="p">((</span><span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="nb">type</span><span class="p">))</span> <span class="ow">and</span>
|
|
<span class="nb">getattr</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="s1">'__typing_is_unpacked_typevartuple__'</span><span class="p">,</span> <span class="kc">False</span><span class="p">))</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_is_typevar_like</span><span class="p">(</span><span class="n">x</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="p">(</span><span class="n">TypeVar</span><span class="p">,</span> <span class="n">ParamSpec</span><span class="p">))</span> <span class="ow">or</span> <span class="n">_is_unpacked_typevartuple</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_typevar_subst</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s2">"Parameters to generic types must be types."</span>
|
|
<span class="n">arg</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">is_argument</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="p">((</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">_GenericAlias</span><span class="p">)</span> <span class="ow">and</span> <span class="n">arg</span><span class="o">.</span><span class="n">__origin__</span> <span class="ow">is</span> <span class="n">Unpack</span><span class="p">)</span> <span class="ow">or</span>
|
|
<span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">GenericAlias</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="s1">'__unpacked__'</span><span class="p">,</span> <span class="kc">False</span><span class="p">))):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">arg</span><span class="si">}</span><span class="s2"> is not valid as type argument"</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">arg</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_typevartuple_prepare_subst</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">alias</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="n">alias</span><span class="o">.</span><span class="n">__parameters__</span>
|
|
<span class="n">typevartuple_index</span> <span class="o">=</span> <span class="n">params</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">params</span><span class="p">[</span><span class="n">typevartuple_index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">:]:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">param</span><span class="p">,</span> <span class="n">TypeVarTuple</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"More than one TypeVarTuple parameter in </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="n">alen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
|
|
<span class="n">plen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
|
|
<span class="n">left</span> <span class="o">=</span> <span class="n">typevartuple_index</span>
|
|
<span class="n">right</span> <span class="o">=</span> <span class="n">plen</span> <span class="o">-</span> <span class="n">typevartuple_index</span> <span class="o">-</span> <span class="mi">1</span>
|
|
<span class="n">var_tuple_index</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">fillarg</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">arg</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">args</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="n">subargs</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="s1">'__typing_unpacked_tuple_args__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">subargs</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">subargs</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">subargs</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="ow">is</span> <span class="o">...</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">var_tuple_index</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"More than one unpacked arbitrary-length tuple argument"</span><span class="p">)</span>
|
|
<span class="n">var_tuple_index</span> <span class="o">=</span> <span class="n">k</span>
|
|
<span class="n">fillarg</span> <span class="o">=</span> <span class="n">subargs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">var_tuple_index</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">left</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">left</span><span class="p">,</span> <span class="n">var_tuple_index</span><span class="p">)</span>
|
|
<span class="n">right</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">right</span><span class="p">,</span> <span class="n">alen</span> <span class="o">-</span> <span class="n">var_tuple_index</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">left</span> <span class="o">+</span> <span class="n">right</span> <span class="o">></span> <span class="n">alen</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Too few arguments for </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">;"</span>
|
|
<span class="sa">f</span><span class="s2">" actual </span><span class="si">{</span><span class="n">alen</span><span class="si">}</span><span class="s2">, expected at least </span><span class="si">{</span><span class="n">plen</span><span class="o">-</span><span class="mi">1</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">left</span> <span class="o">==</span> <span class="n">alen</span> <span class="o">-</span> <span class="n">right</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_default</span><span class="p">():</span>
|
|
<span class="n">replacement</span> <span class="o">=</span> <span class="n">_unpack_args</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__default__</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">replacement</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="n">left</span><span class="p">:</span> <span class="n">alen</span> <span class="o">-</span> <span class="n">right</span><span class="p">]</span>
|
|
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o">*</span><span class="n">args</span><span class="p">[:</span><span class="n">left</span><span class="p">],</span>
|
|
<span class="o">*</span><span class="p">([</span><span class="n">fillarg</span><span class="p">]</span><span class="o">*</span><span class="p">(</span><span class="n">typevartuple_index</span> <span class="o">-</span> <span class="n">left</span><span class="p">)),</span>
|
|
<span class="n">replacement</span><span class="p">,</span>
|
|
<span class="o">*</span><span class="p">([</span><span class="n">fillarg</span><span class="p">]</span><span class="o">*</span><span class="p">(</span><span class="n">plen</span> <span class="o">-</span> <span class="n">right</span> <span class="o">-</span> <span class="n">left</span> <span class="o">-</span> <span class="n">typevartuple_index</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)),</span>
|
|
<span class="o">*</span><span class="n">args</span><span class="p">[</span><span class="n">alen</span> <span class="o">-</span> <span class="n">right</span><span class="p">:],</span>
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_paramspec_subst</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)):</span>
|
|
<span class="n">arg</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_type_check</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="s2">"Expected a type."</span><span class="p">)</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">arg</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="ow">not</span> <span class="n">_is_param_expr</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Expected a list of types, an ellipsis, "</span>
|
|
<span class="sa">f</span><span class="s2">"ParamSpec, or Concatenate. Got </span><span class="si">{</span><span class="n">arg</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">arg</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_paramspec_prepare_subst</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">alias</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="n">alias</span><span class="o">.</span><span class="n">__parameters__</span>
|
|
<span class="n">i</span> <span class="o">=</span> <span class="n">params</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_default</span><span class="p">():</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">__default__</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">i</span> <span class="o">>=</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Too few arguments for </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="c1"># Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612.</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">params</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">_is_param_expr</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
|
|
<span class="k">assert</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">args</span><span class="p">,)</span>
|
|
<span class="c1"># Convert lists to tuples to help other libraries cache the results.</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="nb">list</span><span class="p">):</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">[:</span><span class="n">i</span><span class="p">],</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="n">i</span><span class="p">]),</span> <span class="o">*</span><span class="n">args</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">:])</span>
|
|
<span class="k">return</span> <span class="n">args</span>
|
|
|
|
|
|
<span class="nd">@_tp_cache</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_generic_class_getitem</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Parameterizes a generic class.</span>
|
|
|
|
<span class="sd"> At least, parameterizing a generic class is the *main* thing this method</span>
|
|
<span class="sd"> does. For example, for some generic class `Foo`, this is called when we</span>
|
|
<span class="sd"> do `Foo[int]` - there, with `cls=Foo` and `args=int`.</span>
|
|
|
|
<span class="sd"> However, note that this method is also called when defining generic</span>
|
|
<span class="sd"> classes in the first place with `class Foo(Generic[T]): ...`.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">args</span><span class="p">,)</span>
|
|
|
|
<span class="n">args</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_type_convert</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">args</span><span class="p">)</span>
|
|
<span class="n">is_generic_or_protocol</span> <span class="o">=</span> <span class="bp">cls</span> <span class="ow">in</span> <span class="p">(</span><span class="n">Generic</span><span class="p">,</span> <span class="n">Protocol</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">is_generic_or_protocol</span><span class="p">:</span>
|
|
<span class="c1"># Generic and Protocol can only be subscripted with unique type variables.</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Parameter list to </span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__qualname__</span><span class="si">}</span><span class="s2">[...] cannot be empty"</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">all</span><span class="p">(</span><span class="n">_is_typevar_like</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">args</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Parameters to </span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">[...] must all be type variables "</span>
|
|
<span class="sa">f</span><span class="s2">"or parameter specification variables."</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">args</span><span class="p">))</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Parameters to </span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">[...] must all be unique"</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># Subscripting a regular Generic subclass.</span>
|
|
<span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__parameters__</span><span class="p">:</span>
|
|
<span class="n">prepare</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">param</span><span class="p">,</span> <span class="s1">'__typing_prepare_subst__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">prepare</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="n">prepare</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
|
|
<span class="n">_check_generic_specialization</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
|
|
|
|
<span class="n">new_args</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">param</span><span class="p">,</span> <span class="n">new_arg</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">__parameters__</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">param</span><span class="p">,</span> <span class="n">TypeVarTuple</span><span class="p">):</span>
|
|
<span class="n">new_args</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">new_arg</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">new_args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_arg</span><span class="p">)</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">new_args</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">_GenericAlias</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_generic_init_subclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="nb">super</span><span class="p">(</span><span class="n">Generic</span><span class="p">,</span> <span class="bp">cls</span><span class="p">)</span><span class="o">.</span><span class="n">__init_subclass__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
<span class="n">tvars</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="s1">'__orig_bases__'</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span>
|
|
<span class="n">error</span> <span class="o">=</span> <span class="n">Generic</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__orig_bases__</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">error</span> <span class="o">=</span> <span class="p">(</span><span class="n">Generic</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__bases__</span> <span class="ow">and</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span> <span class="o">!=</span> <span class="s1">'Protocol'</span> <span class="ow">and</span>
|
|
<span class="nb">type</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> <span class="o">!=</span> <span class="n">_TypedDictMeta</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">error</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Cannot inherit from plain Generic"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="s1">'__orig_bases__'</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span>
|
|
<span class="n">tvars</span> <span class="o">=</span> <span class="n">_collect_type_parameters</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">__orig_bases__</span><span class="p">)</span>
|
|
<span class="c1"># Look for Generic[T1, ..., Tn].</span>
|
|
<span class="c1"># If found, tvars must be a subset of it.</span>
|
|
<span class="c1"># If not found, tvars is it.</span>
|
|
<span class="c1"># Also check for and reject plain Generic,</span>
|
|
<span class="c1"># and reject multiple Generic[...].</span>
|
|
<span class="n">gvars</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__orig_bases__</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">_GenericAlias</span><span class="p">)</span> <span class="ow">and</span>
|
|
<span class="n">base</span><span class="o">.</span><span class="n">__origin__</span> <span class="ow">is</span> <span class="n">Generic</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">gvars</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s2">"Cannot inherit from Generic[...] multiple times."</span><span class="p">)</span>
|
|
<span class="n">gvars</span> <span class="o">=</span> <span class="n">base</span><span class="o">.</span><span class="n">__parameters__</span>
|
|
<span class="k">if</span> <span class="n">gvars</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">tvarset</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">tvars</span><span class="p">)</span>
|
|
<span class="n">gvarset</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">gvars</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">tvarset</span> <span class="o"><=</span> <span class="n">gvarset</span><span class="p">:</span>
|
|
<span class="n">s_vars</span> <span class="o">=</span> <span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">tvars</span> <span class="k">if</span> <span class="n">t</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">gvarset</span><span class="p">)</span>
|
|
<span class="n">s_args</span> <span class="o">=</span> <span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">g</span><span class="p">)</span> <span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">gvars</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Some type variables (</span><span class="si">{</span><span class="n">s_vars</span><span class="si">}</span><span class="s2">) are"</span>
|
|
<span class="sa">f</span><span class="s2">" not listed in Generic[</span><span class="si">{</span><span class="n">s_args</span><span class="si">}</span><span class="s2">]"</span><span class="p">)</span>
|
|
<span class="n">tvars</span> <span class="o">=</span> <span class="n">gvars</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">__parameters__</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">tvars</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_is_dunder</span><span class="p">(</span><span class="n">attr</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">attr</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'__'</span><span class="p">)</span> <span class="ow">and</span> <span class="n">attr</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">'__'</span><span class="p">)</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_BaseGenericAlias</span><span class="p">(</span><span class="n">_Final</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""The central part of the internal API.</span>
|
|
|
|
<span class="sd"> This represents a generic version of type 'origin' with type arguments 'params'.</span>
|
|
<span class="sd"> There are two kind of these aliases: user defined and special. The special ones</span>
|
|
<span class="sd"> are wrappers around builtin collections and ABCs in collections.abc. These must</span>
|
|
<span class="sd"> have 'name' always set. If 'inst' is False, then the alias can't be instantiated;</span>
|
|
<span class="sd"> this is used by e.g. typing.List and typing.Dict.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">origin</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_inst</span> <span class="o">=</span> <span class="n">inst</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="n">name</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span> <span class="o">=</span> <span class="n">origin</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="vm">__slots__</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># This is not documented.</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_inst</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Type </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="si">}</span><span class="s2"> cannot be instantiated; "</span>
|
|
<span class="sa">f</span><span class="s2">"use </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">() instead"</span><span class="p">)</span>
|
|
<span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">result</span><span class="o">.</span><span class="n">__orig_class__</span> <span class="o">=</span> <span class="bp">self</span>
|
|
<span class="c1"># Some objects raise TypeError (or something even more exotic)</span>
|
|
<span class="c1"># if you try to set attributes on them; we guard against that here</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">return</span> <span class="n">result</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__mro_entries__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span>
|
|
<span class="n">res</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="n">res</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Check if any base that occurs after us in `bases` is either itself a</span>
|
|
<span class="c1"># subclass of Generic, or something which will add a subclass of Generic</span>
|
|
<span class="c1"># to `__bases__` via its `__mro_entries__`. If not, add Generic</span>
|
|
<span class="c1"># ourselves. The goal is to ensure that Generic (or a subclass) will</span>
|
|
<span class="c1"># appear exactly once in the final bases tuple. If we let it appear</span>
|
|
<span class="c1"># multiple times, we risk "can't form a consistent MRO" errors.</span>
|
|
<span class="n">i</span> <span class="o">=</span> <span class="n">bases</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">:]:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">_BaseGenericAlias</span><span class="p">):</span>
|
|
<span class="k">break</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="n">meth</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="s2">"__mro_entries__"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">new_bases</span> <span class="o">=</span> <span class="n">meth</span><span class="p">(</span><span class="n">bases</span><span class="p">)</span> <span class="k">if</span> <span class="n">meth</span> <span class="k">else</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="nb">isinstance</span><span class="p">(</span><span class="n">new_bases</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span>
|
|
<span class="nb">any</span><span class="p">(</span>
|
|
<span class="nb">isinstance</span><span class="p">(</span><span class="n">b2</span><span class="p">,</span> <span class="nb">type</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">b2</span><span class="p">,</span> <span class="n">Generic</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">b2</span> <span class="ow">in</span> <span class="n">new_bases</span>
|
|
<span class="p">)</span>
|
|
<span class="p">):</span>
|
|
<span class="k">break</span>
|
|
<span class="k">elif</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">Generic</span><span class="p">):</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">res</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Generic</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">res</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">{</span><span class="s1">'__name__'</span><span class="p">,</span> <span class="s1">'__qualname__'</span><span class="p">}:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="o">.</span><span class="vm">__name__</span>
|
|
|
|
<span class="c1"># We are careful for copy and pickle.</span>
|
|
<span class="c1"># Also for simplicity we don't relay any dunder names</span>
|
|
<span class="k">if</span> <span class="s1">'__origin__'</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">_is_dunder</span><span class="p">(</span><span class="n">attr</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,</span> <span class="n">attr</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="n">attr</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__setattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="n">val</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">_is_dunder</span><span class="p">(</span><span class="n">attr</span><span class="p">)</span> <span class="ow">or</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">{</span><span class="s1">'_name'</span><span class="p">,</span> <span class="s1">'_inst'</span><span class="p">,</span> <span class="s1">'_nparams'</span><span class="p">,</span> <span class="s1">'_defaults'</span><span class="p">}:</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__setattr__</span><span class="p">(</span><span class="n">attr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__instancecheck__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__subclasscheck__</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__subclasscheck__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Subscripted generics cannot be used with"</span>
|
|
<span class="s2">" class and instance checks"</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__dir__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__dir__</span><span class="p">()</span>
|
|
<span class="o">+</span> <span class="p">[</span><span class="n">attr</span> <span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="nb">dir</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">_is_dunder</span><span class="p">(</span><span class="n">attr</span><span class="p">)]))</span>
|
|
|
|
|
|
<span class="c1"># Special typing constructs Union, Optional, Generic, Callable and Tuple</span>
|
|
<span class="c1"># use three special attributes for internal bookkeeping of generic types:</span>
|
|
<span class="c1"># * __parameters__ is a tuple of unique free type parameters of a generic</span>
|
|
<span class="c1"># type, for example, Dict[T, T].__parameters__ == (T,);</span>
|
|
<span class="c1"># * __origin__ keeps a reference to a type that was subscripted,</span>
|
|
<span class="c1"># e.g., Union[T, int].__origin__ == Union, or the non-generic version of</span>
|
|
<span class="c1"># the type.</span>
|
|
<span class="c1"># * __args__ is a tuple of all arguments used in subscripting,</span>
|
|
<span class="c1"># e.g., Dict[T, int].__args__ == (T, int).</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_GenericAlias</span><span class="p">(</span><span class="n">_BaseGenericAlias</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="c1"># The type of parameterized generics.</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># That is, for example, `type(List[int])` is `_GenericAlias`.</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># Objects which are instances of this class include:</span>
|
|
<span class="c1"># * Parameterized container types, e.g. `Tuple[int]`, `List[int]`.</span>
|
|
<span class="c1"># * Note that native container types, e.g. `tuple`, `list`, use</span>
|
|
<span class="c1"># `types.GenericAlias` instead.</span>
|
|
<span class="c1"># * Parameterized classes:</span>
|
|
<span class="c1"># class C[T]: pass</span>
|
|
<span class="c1"># # C[int] is a _GenericAlias</span>
|
|
<span class="c1"># * `Callable` aliases, generic `Callable` aliases, and</span>
|
|
<span class="c1"># parameterized `Callable` aliases:</span>
|
|
<span class="c1"># T = TypeVar('T')</span>
|
|
<span class="c1"># # _CallableGenericAlias inherits from _GenericAlias.</span>
|
|
<span class="c1"># A = Callable[[], None] # _CallableGenericAlias</span>
|
|
<span class="c1"># B = Callable[[T], None] # _CallableGenericAlias</span>
|
|
<span class="c1"># C = B[int] # _CallableGenericAlias</span>
|
|
<span class="c1"># * Parameterized `Final`, `ClassVar`, `TypeGuard`, and `TypeIs`:</span>
|
|
<span class="c1"># # All _GenericAlias</span>
|
|
<span class="c1"># Final[int]</span>
|
|
<span class="c1"># ClassVar[float]</span>
|
|
<span class="c1"># TypeGuard[bool]</span>
|
|
<span class="c1"># TypeIs[range]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">origin</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">origin</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="n">inst</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">args</span><span class="p">,)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__args__</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="o">...</span> <span class="k">if</span> <span class="n">a</span> <span class="ow">is</span> <span class="n">_TypingEllipsis</span> <span class="k">else</span>
|
|
<span class="n">a</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">args</span><span class="p">)</span>
|
|
<span class="n">enforce_default_ordering</span> <span class="o">=</span> <span class="n">origin</span> <span class="ow">in</span> <span class="p">(</span><span class="n">Generic</span><span class="p">,</span> <span class="n">Protocol</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__parameters__</span> <span class="o">=</span> <span class="n">_collect_type_parameters</span><span class="p">(</span>
|
|
<span class="n">args</span><span class="p">,</span>
|
|
<span class="n">enforce_default_ordering</span><span class="o">=</span><span class="n">enforce_default_ordering</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">name</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span> <span class="o">=</span> <span class="n">origin</span><span class="o">.</span><span class="vm">__module__</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">_GenericAlias</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">__origin__</span>
|
|
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">__args__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">hash</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__or__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">right</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="bp">self</span><span class="p">,</span> <span class="n">right</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__ror__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">left</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="n">left</span><span class="p">,</span> <span class="bp">self</span><span class="p">]</span>
|
|
|
|
<span class="nd">@_tp_cache</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
|
<span class="c1"># Parameterizes an already-parameterized object.</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># For example, we arrive here doing something like:</span>
|
|
<span class="c1"># T1 = TypeVar('T1')</span>
|
|
<span class="c1"># T2 = TypeVar('T2')</span>
|
|
<span class="c1"># T3 = TypeVar('T3')</span>
|
|
<span class="c1"># class A(Generic[T1]): pass</span>
|
|
<span class="c1"># B = A[T2] # B is a _GenericAlias</span>
|
|
<span class="c1"># C = B[T3] # Invokes _GenericAlias.__getitem__</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># We also arrive here when parameterizing a generic `Callable` alias:</span>
|
|
<span class="c1"># T = TypeVar('T')</span>
|
|
<span class="c1"># C = Callable[[T], None]</span>
|
|
<span class="c1"># C[int] # Invokes _GenericAlias.__getitem__</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span> <span class="ow">in</span> <span class="p">(</span><span class="n">Generic</span><span class="p">,</span> <span class="n">Protocol</span><span class="p">):</span>
|
|
<span class="c1"># Can't subscript Generic[...] or Protocol[...].</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Cannot subscript already-subscripted </span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">__parameters__</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2"> is not a generic class"</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Preprocess `args`.</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">args</span><span class="p">,)</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="n">_unpack_args</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">_type_convert</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">args</span><span class="p">))</span>
|
|
<span class="n">new_args</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_determine_new_args</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
|
|
<span class="n">r</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy_with</span><span class="p">(</span><span class="n">new_args</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">r</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_determine_new_args</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
|
<span class="c1"># Determines new __args__ for __getitem__.</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># For example, suppose we had:</span>
|
|
<span class="c1"># T1 = TypeVar('T1')</span>
|
|
<span class="c1"># T2 = TypeVar('T2')</span>
|
|
<span class="c1"># class A(Generic[T1, T2]): pass</span>
|
|
<span class="c1"># T3 = TypeVar('T3')</span>
|
|
<span class="c1"># B = A[int, T3]</span>
|
|
<span class="c1"># C = B[str]</span>
|
|
<span class="c1"># `B.__args__` is `(int, T3)`, so `C.__args__` should be `(int, str)`.</span>
|
|
<span class="c1"># Unfortunately, this is harder than it looks, because if `T3` is</span>
|
|
<span class="c1"># anything more exotic than a plain `TypeVar`, we need to consider</span>
|
|
<span class="c1"># edge cases.</span>
|
|
|
|
<span class="n">params</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__parameters__</span>
|
|
<span class="c1"># In the example above, this would be {T3: str}</span>
|
|
<span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">params</span><span class="p">:</span>
|
|
<span class="n">prepare</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">param</span><span class="p">,</span> <span class="s1">'__typing_prepare_subst__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">prepare</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="n">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
|
|
<span class="n">alen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
|
|
<span class="n">plen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">alen</span> <span class="o">!=</span> <span class="n">plen</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Too </span><span class="si">{</span><span class="s1">'many'</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">alen</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">plen</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="s1">'few'</span><span class="si">}</span><span class="s2"> arguments for </span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2">;"</span>
|
|
<span class="sa">f</span><span class="s2">" actual </span><span class="si">{</span><span class="n">alen</span><span class="si">}</span><span class="s2">, expected </span><span class="si">{</span><span class="n">plen</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="n">new_arg_by_param</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="n">args</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_make_substitution</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">,</span> <span class="n">new_arg_by_param</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_make_substitution</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">new_arg_by_param</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Create a list of new type arguments."""</span>
|
|
<span class="n">new_args</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">old_arg</span> <span class="ow">in</span> <span class="n">args</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">old_arg</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="n">new_args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">old_arg</span><span class="p">)</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="n">substfunc</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">old_arg</span><span class="p">,</span> <span class="s1">'__typing_subst__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">substfunc</span><span class="p">:</span>
|
|
<span class="n">new_arg</span> <span class="o">=</span> <span class="n">substfunc</span><span class="p">(</span><span class="n">new_arg_by_param</span><span class="p">[</span><span class="n">old_arg</span><span class="p">])</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">subparams</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">old_arg</span><span class="p">,</span> <span class="s1">'__parameters__'</span><span class="p">,</span> <span class="p">())</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">subparams</span><span class="p">:</span>
|
|
<span class="n">new_arg</span> <span class="o">=</span> <span class="n">old_arg</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">subargs</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">subparams</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">TypeVarTuple</span><span class="p">):</span>
|
|
<span class="n">subargs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">new_arg_by_param</span><span class="p">[</span><span class="n">x</span><span class="p">])</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">subargs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_arg_by_param</span><span class="p">[</span><span class="n">x</span><span class="p">])</span>
|
|
<span class="n">new_arg</span> <span class="o">=</span> <span class="n">old_arg</span><span class="p">[</span><span class="nb">tuple</span><span class="p">(</span><span class="n">subargs</span><span class="p">)]</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span> <span class="o">==</span> <span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Callable</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">new_arg</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="c1"># Consider the following `Callable`.</span>
|
|
<span class="c1"># C = Callable[[int], str]</span>
|
|
<span class="c1"># Here, `C.__args__` should be (int, str) - NOT ([int], str).</span>
|
|
<span class="c1"># That means that if we had something like...</span>
|
|
<span class="c1"># P = ParamSpec('P')</span>
|
|
<span class="c1"># T = TypeVar('T')</span>
|
|
<span class="c1"># C = Callable[P, T]</span>
|
|
<span class="c1"># D = C[[int, str], float]</span>
|
|
<span class="c1"># ...we need to be careful; `new_args` should end up as</span>
|
|
<span class="c1"># `(int, str, float)` rather than `([int, str], float)`.</span>
|
|
<span class="n">new_args</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">new_arg</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">_is_unpacked_typevartuple</span><span class="p">(</span><span class="n">old_arg</span><span class="p">):</span>
|
|
<span class="c1"># Consider the following `_GenericAlias`, `B`:</span>
|
|
<span class="c1"># class A(Generic[*Ts]): ...</span>
|
|
<span class="c1"># B = A[T, *Ts]</span>
|
|
<span class="c1"># If we then do:</span>
|
|
<span class="c1"># B[float, int, str]</span>
|
|
<span class="c1"># The `new_arg` corresponding to `T` will be `float`, and the</span>
|
|
<span class="c1"># `new_arg` corresponding to `*Ts` will be `(int, str)`. We</span>
|
|
<span class="c1"># should join all these types together in a flat list</span>
|
|
<span class="c1"># `(float, int, str)` - so again, we should `extend`.</span>
|
|
<span class="n">new_args</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">new_arg</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">old_arg</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="c1"># Corner case:</span>
|
|
<span class="c1"># P = ParamSpec('P')</span>
|
|
<span class="c1"># T = TypeVar('T')</span>
|
|
<span class="c1"># class Base(Generic[P]): ...</span>
|
|
<span class="c1"># Can be substituted like this:</span>
|
|
<span class="c1"># X = Base[[int, T]]</span>
|
|
<span class="c1"># In this case, `old_arg` will be a tuple:</span>
|
|
<span class="n">new_args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
|
|
<span class="nb">tuple</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_make_substitution</span><span class="p">(</span><span class="n">old_arg</span><span class="p">,</span> <span class="n">new_arg_by_param</span><span class="p">)),</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">new_args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_arg</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">new_args</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">copy_with</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_inst</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">:</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="s1">'typing.'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">_type_repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">:</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">_type_repr</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">])</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># To ensure the repr is eval-able.</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="s2">"()"</span>
|
|
<span class="k">return</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s1">[</span><span class="si">{</span><span class="n">args</span><span class="si">}</span><span class="s1">]'</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">:</span>
|
|
<span class="n">origin</span> <span class="o">=</span> <span class="nb">globals</span><span class="p">()[</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">origin</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">args</span><span class="p">,</span> <span class="o">=</span> <span class="n">args</span>
|
|
<span class="k">return</span> <span class="n">operator</span><span class="o">.</span><span class="n">getitem</span><span class="p">,</span> <span class="p">(</span><span class="n">origin</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__mro_entries__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,</span> <span class="n">_SpecialForm</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Cannot subclass </span><span class="si">{</span><span class="bp">self</span><span class="si">!r}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">:</span> <span class="c1"># generic version of an ABC or built-in class</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__mro_entries__</span><span class="p">(</span><span class="n">bases</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span> <span class="ow">is</span> <span class="n">Generic</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">Protocol</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="p">()</span>
|
|
<span class="n">i</span> <span class="o">=</span> <span class="n">bases</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">:]:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">_BaseGenericAlias</span><span class="p">)</span> <span class="ow">and</span> <span class="n">b</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">self</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="p">()</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">yield</span> <span class="n">Unpack</span><span class="p">[</span><span class="bp">self</span><span class="p">]</span>
|
|
|
|
|
|
<span class="c1"># _nparams is the number of accepted parameters, e.g. 0 for Hashable,</span>
|
|
<span class="c1"># 1 for List and 2 for Dict. It may be -1 if variable number of</span>
|
|
<span class="c1"># parameters are accepted (needs custom __getitem__).</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_SpecialGenericAlias</span><span class="p">(</span><span class="n">_NotIterable</span><span class="p">,</span> <span class="n">_BaseGenericAlias</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">origin</span><span class="p">,</span> <span class="n">nparams</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="p">()):</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">origin</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">origin</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="n">inst</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_nparams</span> <span class="o">=</span> <span class="n">nparams</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_defaults</span> <span class="o">=</span> <span class="n">defaults</span>
|
|
<span class="k">if</span> <span class="n">origin</span><span class="o">.</span><span class="vm">__module__</span> <span class="o">==</span> <span class="s1">'builtins'</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="vm">__doc__</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">'A generic version of </span><span class="si">{</span><span class="n">origin</span><span class="o">.</span><span class="vm">__qualname__</span><span class="si">}</span><span class="s1">.'</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="vm">__doc__</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">'A generic version of </span><span class="si">{</span><span class="n">origin</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s1">.</span><span class="si">{</span><span class="n">origin</span><span class="o">.</span><span class="vm">__qualname__</span><span class="si">}</span><span class="s1">.'</span>
|
|
|
|
<span class="nd">@_tp_cache</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="p">(</span><span class="n">params</span><span class="p">,)</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s2">"Parameters to generic types must be types."</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_type_check</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">params</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_defaults</span>
|
|
<span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">params</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nparams</span>
|
|
<span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">params</span><span class="p">)</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_defaults</span><span class="p">)</span> <span class="o">>=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nparams</span>
|
|
<span class="p">):</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">params</span><span class="p">,</span> <span class="o">*</span><span class="bp">self</span><span class="o">.</span><span class="n">_defaults</span><span class="p">[</span><span class="nb">len</span><span class="p">(</span><span class="n">params</span><span class="p">)</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nparams</span><span class="p">:])</span>
|
|
<span class="n">actual_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">actual_len</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nparams</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_defaults</span><span class="p">:</span>
|
|
<span class="n">expected</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"at least </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_nparams</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_defaults</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">expected</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_nparams</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nparams</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2"> is not a generic class"</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Too </span><span class="si">{</span><span class="s1">'many'</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">actual_len</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="bp">self</span><span class="o">.</span><span class="n">_nparams</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="s1">'few'</span><span class="si">}</span><span class="s2"> arguments for </span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2">;"</span>
|
|
<span class="sa">f</span><span class="s2">" actual </span><span class="si">{</span><span class="n">actual_len</span><span class="si">}</span><span class="s2">, expected </span><span class="si">{</span><span class="n">expected</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy_with</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">copy_with</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">_GenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span>
|
|
<span class="n">name</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_inst</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="s1">'typing.'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__subclasscheck__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">_SpecialGenericAlias</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">_GenericAlias</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__subclasscheck__</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__or__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">right</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="bp">self</span><span class="p">,</span> <span class="n">right</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__ror__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">left</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="n">left</span><span class="p">,</span> <span class="bp">self</span><span class="p">]</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_DeprecatedGenericAlias</span><span class="p">(</span><span class="n">_SpecialGenericAlias</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">origin</span><span class="p">,</span> <span class="n">nparams</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">removal_version</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span>
|
|
<span class="p">):</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">origin</span><span class="p">,</span> <span class="n">nparams</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="n">inst</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_removal_version</span> <span class="o">=</span> <span class="n">removal_version</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__instancecheck__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inst</span><span class="p">):</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">warnings</span>
|
|
<span class="n">warnings</span><span class="o">.</span><span class="n">_deprecated</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span> <span class="n">remove</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_removal_version</span>
|
|
<span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__instancecheck__</span><span class="p">(</span><span class="n">inst</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_CallableGenericAlias</span><span class="p">(</span><span class="n">_NotIterable</span><span class="p">,</span> <span class="n">_GenericAlias</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">==</span> <span class="s1">'Callable'</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__args__</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">_is_param_expr</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__repr__</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="sa">f</span><span class="s1">'typing.Callable'</span>
|
|
<span class="sa">f</span><span class="s1">'[[</span><span class="si">{</span><span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">_type_repr</span><span class="p">(</span><span class="n">a</span><span class="p">)</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">args</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]])</span><span class="si">}</span><span class="s1">], '</span>
|
|
<span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">_type_repr</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span><span class="si">}</span><span class="s1">]'</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__args__</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">_is_param_expr</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])):</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">args</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]),</span> <span class="n">args</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="n">operator</span><span class="o">.</span><span class="n">getitem</span><span class="p">,</span> <span class="p">(</span><span class="n">Callable</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_CallableType</span><span class="p">(</span><span class="n">_SpecialGenericAlias</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">copy_with</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">_CallableGenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span>
|
|
<span class="n">name</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_inst</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">params</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Callable must be used as "</span>
|
|
<span class="s2">"Callable[[arg, ...], result]."</span><span class="p">)</span>
|
|
<span class="n">args</span><span class="p">,</span> <span class="n">result</span> <span class="o">=</span> <span class="n">params</span>
|
|
<span class="c1"># This relaxes what args can be on purpose to allow things like</span>
|
|
<span class="c1"># PEP 612 ParamSpec. Responsibility for whether a user is using</span>
|
|
<span class="c1"># Callable[...] properly is deferred to static type checkers.</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="p">(</span><span class="nb">tuple</span><span class="p">(</span><span class="n">args</span><span class="p">),</span> <span class="n">result</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">result</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__getitem_inner__</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
|
|
|
|
<span class="nd">@_tp_cache</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__getitem_inner__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
|
|
<span class="n">args</span><span class="p">,</span> <span class="n">result</span> <span class="o">=</span> <span class="n">params</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s2">"Callable[args, result]: result must be a type."</span>
|
|
<span class="n">result</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">args</span> <span class="ow">is</span> <span class="bp">Ellipsis</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy_with</span><span class="p">((</span><span class="n">_TypingEllipsis</span><span class="p">,</span> <span class="n">result</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">args</span><span class="p">,)</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_type_convert</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">args</span><span class="p">)</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="n">args</span> <span class="o">+</span> <span class="p">(</span><span class="n">result</span><span class="p">,)</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy_with</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_TupleType</span><span class="p">(</span><span class="n">_SpecialGenericAlias</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="nd">@_tp_cache</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="p">(</span><span class="n">params</span><span class="p">,)</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">params</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">params</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="ow">is</span> <span class="o">...</span><span class="p">:</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s2">"Tuple[t, ...]: t must be a type."</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_type_check</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">params</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy_with</span><span class="p">((</span><span class="o">*</span><span class="n">params</span><span class="p">,</span> <span class="n">_TypingEllipsis</span><span class="p">))</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s2">"Tuple[t0, t1, ...]: each t must be a type."</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_type_check</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">params</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy_with</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_UnionGenericAlias</span><span class="p">(</span><span class="n">_NotIterable</span><span class="p">,</span> <span class="n">_GenericAlias</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">copy_with</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="n">params</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="p">(</span><span class="n">_UnionGenericAlias</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">UnionType</span><span class="p">)):</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
<span class="k">try</span><span class="p">:</span> <span class="c1"># fast path</span>
|
|
<span class="k">return</span> <span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span> <span class="o">==</span> <span class="nb">set</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> <span class="c1"># not hashable, slow path</span>
|
|
<span class="k">return</span> <span class="n">_compare_args_orderless</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">frozenset</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__args__</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">is</span> <span class="nb">type</span><span class="p">(</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="sa">f</span><span class="s1">'typing.Optional[</span><span class="si">{</span><span class="n">_type_repr</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span><span class="si">}</span><span class="s1">]'</span>
|
|
<span class="k">elif</span> <span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="ow">is</span> <span class="nb">type</span><span class="p">(</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="sa">f</span><span class="s1">'typing.Optional[</span><span class="si">{</span><span class="n">_type_repr</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span><span class="si">}</span><span class="s1">]'</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__repr__</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__instancecheck__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
|
|
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__subclasscheck__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">func</span><span class="p">,</span> <span class="p">(</span><span class="n">origin</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__reduce__</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="n">func</span><span class="p">,</span> <span class="p">(</span><span class="n">Union</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_value_and_type_iter</span><span class="p">(</span><span class="n">parameters</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="p">((</span><span class="n">p</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="n">p</span><span class="p">))</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">parameters</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_LiteralGenericAlias</span><span class="p">(</span><span class="n">_GenericAlias</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">_LiteralGenericAlias</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="k">return</span> <span class="nb">set</span><span class="p">(</span><span class="n">_value_and_type_iter</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">))</span> <span class="o">==</span> <span class="nb">set</span><span class="p">(</span><span class="n">_value_and_type_iter</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">__args__</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">frozenset</span><span class="p">(</span><span class="n">_value_and_type_iter</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">)))</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_ConcatenateGenericAlias</span><span class="p">(</span><span class="n">_GenericAlias</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">copy_with</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)):</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="o">*</span><span class="n">params</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="o">*</span><span class="n">params</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">_ConcatenateGenericAlias</span><span class="p">):</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">params</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="o">*</span><span class="n">params</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">copy_with</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
|
|
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">Unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Type unpack operator.</span>
|
|
|
|
<span class="sd"> The type unpack operator takes the child types from some container type,</span>
|
|
<span class="sd"> such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> # For some generic class `Foo`:</span>
|
|
<span class="sd"> Foo[Unpack[tuple[int, str]]] # Equivalent to Foo[int, str]</span>
|
|
|
|
<span class="sd"> Ts = TypeVarTuple('Ts')</span>
|
|
<span class="sd"> # Specifies that `Bar` is generic in an arbitrary number of types.</span>
|
|
<span class="sd"> # (Think of `Ts` as a tuple of an arbitrary number of individual</span>
|
|
<span class="sd"> # `TypeVar`s, which the `Unpack` is 'pulling out' directly into the</span>
|
|
<span class="sd"> # `Generic[]`.)</span>
|
|
<span class="sd"> class Bar(Generic[Unpack[Ts]]): ...</span>
|
|
<span class="sd"> Bar[int] # Valid</span>
|
|
<span class="sd"> Bar[int, str] # Also valid</span>
|
|
|
|
<span class="sd"> From Python 3.11, this can also be done using the `*` operator::</span>
|
|
|
|
<span class="sd"> Foo[*tuple[int, str]]</span>
|
|
<span class="sd"> class Bar(Generic[*Ts]): ...</span>
|
|
|
|
<span class="sd"> And from Python 3.12, it can be done using built-in syntax for generics::</span>
|
|
|
|
<span class="sd"> Foo[*tuple[int, str]]</span>
|
|
<span class="sd"> class Bar[*Ts]: ...</span>
|
|
|
|
<span class="sd"> The operator can also be used along with a `TypedDict` to annotate</span>
|
|
<span class="sd"> `**kwargs` in a function signature::</span>
|
|
|
|
<span class="sd"> class Movie(TypedDict):</span>
|
|
<span class="sd"> name: str</span>
|
|
<span class="sd"> year: int</span>
|
|
|
|
<span class="sd"> # This function expects two keyword arguments - *name* of type `str` and</span>
|
|
<span class="sd"> # *year* of type `int`.</span>
|
|
<span class="sd"> def foo(**kwargs: Unpack[Movie]): ...</span>
|
|
|
|
<span class="sd"> Note that there is only some runtime checking of this operator. Not</span>
|
|
<span class="sd"> everything the runtime allows may be accepted by static type checkers.</span>
|
|
|
|
<span class="sd"> For more information, see PEPs 646 and 692.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">item</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s1"> accepts only single type.'</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_UnpackGenericAlias</span><span class="p">(</span><span class="n">origin</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">item</span><span class="p">,))</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_UnpackGenericAlias</span><span class="p">(</span><span class="n">_GenericAlias</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="c1"># `Unpack` only takes one argument, so __args__ should contain only</span>
|
|
<span class="c1"># a single item.</span>
|
|
<span class="k">return</span> <span class="sa">f</span><span class="s1">'typing.Unpack[</span><span class="si">{</span><span class="n">_type_repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span><span class="si">}</span><span class="s1">]'</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__typing_is_unpacked_typevartuple__</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">args</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__getitem__</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__typing_unpacked_tuple_args__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span> <span class="ow">is</span> <span class="n">Unpack</span>
|
|
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
|
|
<span class="n">arg</span><span class="p">,</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__args__</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="p">(</span><span class="n">_GenericAlias</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">GenericAlias</span><span class="p">)):</span>
|
|
<span class="k">if</span> <span class="n">arg</span><span class="o">.</span><span class="n">__origin__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">tuple</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Unpack[...] must be used with a tuple type"</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">arg</span><span class="o">.</span><span class="n">__args__</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__typing_is_unpacked_typevartuple__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span> <span class="ow">is</span> <span class="n">Unpack</span>
|
|
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__args__</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">TypeVarTuple</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_TypingEllipsis</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Internal placeholder for ... (ellipsis)."""</span>
|
|
|
|
|
|
<span class="n">_TYPING_INTERNALS</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span>
|
|
<span class="s1">'__parameters__'</span><span class="p">,</span> <span class="s1">'__orig_bases__'</span><span class="p">,</span> <span class="s1">'__orig_class__'</span><span class="p">,</span>
|
|
<span class="s1">'_is_protocol'</span><span class="p">,</span> <span class="s1">'_is_runtime_protocol'</span><span class="p">,</span> <span class="s1">'__protocol_attrs__'</span><span class="p">,</span>
|
|
<span class="s1">'__non_callable_proto_members__'</span><span class="p">,</span> <span class="s1">'__type_params__'</span><span class="p">,</span>
|
|
<span class="p">})</span>
|
|
|
|
<span class="n">_SPECIAL_NAMES</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span>
|
|
<span class="s1">'__abstractmethods__'</span><span class="p">,</span> <span class="s1">'__annotations__'</span><span class="p">,</span> <span class="s1">'__dict__'</span><span class="p">,</span> <span class="s1">'__doc__'</span><span class="p">,</span>
|
|
<span class="s1">'__init__'</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">,</span> <span class="s1">'__new__'</span><span class="p">,</span> <span class="s1">'__slots__'</span><span class="p">,</span>
|
|
<span class="s1">'__subclasshook__'</span><span class="p">,</span> <span class="s1">'__weakref__'</span><span class="p">,</span> <span class="s1">'__class_getitem__'</span><span class="p">,</span>
|
|
<span class="s1">'__match_args__'</span><span class="p">,</span> <span class="s1">'__static_attributes__'</span><span class="p">,</span> <span class="s1">'__firstlineno__'</span><span class="p">,</span>
|
|
<span class="p">})</span>
|
|
|
|
<span class="c1"># These special attributes will be not collected as protocol members.</span>
|
|
<span class="n">EXCLUDED_ATTRIBUTES</span> <span class="o">=</span> <span class="n">_TYPING_INTERNALS</span> <span class="o">|</span> <span class="n">_SPECIAL_NAMES</span> <span class="o">|</span> <span class="p">{</span><span class="s1">'_MutableMapping__marker'</span><span class="p">}</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_get_protocol_attrs</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Collect protocol members from a protocol class objects.</span>
|
|
|
|
<span class="sd"> This includes names actually defined in the class dictionary, as well</span>
|
|
<span class="sd"> as names that appear in annotations. Special names (above) are skipped.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">attrs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span> <span class="c1"># without object</span>
|
|
<span class="k">if</span> <span class="n">base</span><span class="o">.</span><span class="vm">__name__</span> <span class="ow">in</span> <span class="p">{</span><span class="s1">'Protocol'</span><span class="p">,</span> <span class="s1">'Generic'</span><span class="p">}:</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">annotations</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="s1">'__annotations__'</span><span class="p">,</span> <span class="p">{})</span>
|
|
<span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">(</span><span class="o">*</span><span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">,</span> <span class="o">*</span><span class="n">annotations</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">attr</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'_abc_'</span><span class="p">)</span> <span class="ow">and</span> <span class="n">attr</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">EXCLUDED_ATTRIBUTES</span><span class="p">:</span>
|
|
<span class="n">attrs</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">attr</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">attrs</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_no_init_or_replace_init</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_is_protocol</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Protocols cannot be instantiated'</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Already using a custom `__init__`. No need to calculate correct</span>
|
|
<span class="c1"># `__init__` to call. This can lead to RecursionError. See bpo-45121.</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="fm">__init__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_no_init_or_replace_init</span><span class="p">:</span>
|
|
<span class="k">return</span>
|
|
|
|
<span class="c1"># Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`.</span>
|
|
<span class="c1"># The first instantiation of the subclass will call `_no_init_or_replace_init` which</span>
|
|
<span class="c1"># searches for a proper new `__init__` in the MRO. The new `__init__`</span>
|
|
<span class="c1"># replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent</span>
|
|
<span class="c1"># instantiation of the protocol subclass will thus use the new</span>
|
|
<span class="c1"># `__init__` and no longer call `_no_init_or_replace_init`.</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">:</span>
|
|
<span class="n">init</span> <span class="o">=</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__init__'</span><span class="p">,</span> <span class="n">_no_init_or_replace_init</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">init</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_no_init_or_replace_init</span><span class="p">:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="fm">__init__</span> <span class="o">=</span> <span class="n">init</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># should not happen</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="fm">__init__</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__init__</span>
|
|
|
|
<span class="bp">cls</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_caller</span><span class="p">(</span><span class="n">depth</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s1">'__main__'</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">sys</span><span class="o">.</span><span class="n">_getframemodulename</span><span class="p">(</span><span class="n">depth</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="ow">or</span> <span class="n">default</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span> <span class="c1"># For platforms without _getframemodulename()</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">sys</span><span class="o">.</span><span class="n">_getframe</span><span class="p">(</span><span class="n">depth</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">f_globals</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__name__'</span><span class="p">,</span> <span class="n">default</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">AttributeError</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">):</span> <span class="c1"># For platforms without _getframe()</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_allow_reckless_class_checks</span><span class="p">(</span><span class="n">depth</span><span class="o">=</span><span class="mi">2</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Allow instance and class checks for special stdlib modules.</span>
|
|
|
|
<span class="sd"> The abc and functools modules indiscriminately call isinstance() and</span>
|
|
<span class="sd"> issubclass() on the whole MRO of a user class, which may contain protocols.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">_caller</span><span class="p">(</span><span class="n">depth</span><span class="p">)</span> <span class="ow">in</span> <span class="p">{</span><span class="s1">'abc'</span><span class="p">,</span> <span class="s1">'functools'</span><span class="p">,</span> <span class="kc">None</span><span class="p">}</span>
|
|
|
|
|
|
<span class="n">_PROTO_ALLOWLIST</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s1">'collections.abc'</span><span class="p">:</span> <span class="p">[</span>
|
|
<span class="s1">'Callable'</span><span class="p">,</span> <span class="s1">'Awaitable'</span><span class="p">,</span> <span class="s1">'Iterable'</span><span class="p">,</span> <span class="s1">'Iterator'</span><span class="p">,</span> <span class="s1">'AsyncIterable'</span><span class="p">,</span>
|
|
<span class="s1">'AsyncIterator'</span><span class="p">,</span> <span class="s1">'Hashable'</span><span class="p">,</span> <span class="s1">'Sized'</span><span class="p">,</span> <span class="s1">'Container'</span><span class="p">,</span> <span class="s1">'Collection'</span><span class="p">,</span>
|
|
<span class="s1">'Reversible'</span><span class="p">,</span> <span class="s1">'Buffer'</span><span class="p">,</span>
|
|
<span class="p">],</span>
|
|
<span class="s1">'contextlib'</span><span class="p">:</span> <span class="p">[</span><span class="s1">'AbstractContextManager'</span><span class="p">,</span> <span class="s1">'AbstractAsyncContextManager'</span><span class="p">],</span>
|
|
<span class="p">}</span>
|
|
|
|
|
|
<span class="nd">@functools</span><span class="o">.</span><span class="n">cache</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_lazy_load_getattr_static</span><span class="p">():</span>
|
|
<span class="c1"># Import getattr_static lazily so as not to slow down the import of typing.py</span>
|
|
<span class="c1"># Cache the result so we don't slow down _ProtocolMeta.__instancecheck__ unnecessarily</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">inspect</span><span class="w"> </span><span class="kn">import</span> <span class="n">getattr_static</span>
|
|
<span class="k">return</span> <span class="n">getattr_static</span>
|
|
|
|
|
|
<span class="n">_cleanups</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_lazy_load_getattr_static</span><span class="o">.</span><span class="n">cache_clear</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_pickle_psargs</span><span class="p">(</span><span class="n">psargs</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">ParamSpecArgs</span><span class="p">,</span> <span class="p">(</span><span class="n">psargs</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,)</span>
|
|
|
|
<span class="n">copyreg</span><span class="o">.</span><span class="n">pickle</span><span class="p">(</span><span class="n">ParamSpecArgs</span><span class="p">,</span> <span class="n">_pickle_psargs</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_pickle_pskwargs</span><span class="p">(</span><span class="n">pskwargs</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">ParamSpecKwargs</span><span class="p">,</span> <span class="p">(</span><span class="n">pskwargs</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,)</span>
|
|
|
|
<span class="n">copyreg</span><span class="o">.</span><span class="n">pickle</span><span class="p">(</span><span class="n">ParamSpecKwargs</span><span class="p">,</span> <span class="n">_pickle_pskwargs</span><span class="p">)</span>
|
|
|
|
<span class="k">del</span> <span class="n">_pickle_psargs</span><span class="p">,</span> <span class="n">_pickle_pskwargs</span>
|
|
|
|
|
|
<span class="c1"># Preload these once, as globals, as a micro-optimisation.</span>
|
|
<span class="c1"># This makes a significant difference to the time it takes</span>
|
|
<span class="c1"># to do `isinstance()`/`issubclass()` checks</span>
|
|
<span class="c1"># against runtime-checkable protocols with only one callable member.</span>
|
|
<span class="n">_abc_instancecheck</span> <span class="o">=</span> <span class="n">ABCMeta</span><span class="o">.</span><span class="fm">__instancecheck__</span>
|
|
<span class="n">_abc_subclasscheck</span> <span class="o">=</span> <span class="n">ABCMeta</span><span class="o">.</span><span class="fm">__subclasscheck__</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_type_check_issubclass_arg_1</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Raise TypeError if `arg` is not an instance of `type`</span>
|
|
<span class="sd"> in `issubclass(arg, <protocol>)`.</span>
|
|
|
|
<span class="sd"> In most cases, this is verified by type.__subclasscheck__.</span>
|
|
<span class="sd"> Checking it again unnecessarily would slow down issubclass() checks,</span>
|
|
<span class="sd"> so, we don't perform this check unless we absolutely have to.</span>
|
|
|
|
<span class="sd"> For various error paths, however,</span>
|
|
<span class="sd"> we want to ensure that *this* error message is shown to the user</span>
|
|
<span class="sd"> where relevant, rather than a typing.py-specific error message.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="c1"># Same error message as for issubclass(1, int).</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'issubclass() arg 1 must be a class'</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_ProtocolMeta</span><span class="p">(</span><span class="n">ABCMeta</span><span class="p">):</span>
|
|
<span class="c1"># This metaclass is somewhat unfortunate,</span>
|
|
<span class="c1"># but is necessary for several reasons...</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="n">mcls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">namespace</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s2">"Protocol"</span> <span class="ow">and</span> <span class="n">bases</span> <span class="o">==</span> <span class="p">(</span><span class="n">Generic</span><span class="p">,):</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">elif</span> <span class="n">Protocol</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span>
|
|
<span class="n">base</span> <span class="ow">in</span> <span class="p">{</span><span class="nb">object</span><span class="p">,</span> <span class="n">Generic</span><span class="p">}</span>
|
|
<span class="ow">or</span> <span class="n">base</span><span class="o">.</span><span class="vm">__name__</span> <span class="ow">in</span> <span class="n">_PROTO_ALLOWLIST</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">base</span><span class="o">.</span><span class="vm">__module__</span><span class="p">,</span> <span class="p">[])</span>
|
|
<span class="ow">or</span> <span class="p">(</span>
|
|
<span class="nb">issubclass</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">Generic</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="s2">"_is_protocol"</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Protocols can only inherit from other protocols, "</span>
|
|
<span class="sa">f</span><span class="s2">"got </span><span class="si">{</span><span class="n">base</span><span class="si">!r}</span><span class="s2">"</span>
|
|
<span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="n">mcls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">namespace</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="s2">"_is_protocol"</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">__protocol_attrs__</span> <span class="o">=</span> <span class="n">_get_protocol_attrs</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__subclasscheck__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">cls</span> <span class="ow">is</span> <span class="n">Protocol</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="nb">type</span><span class="o">.</span><span class="fm">__subclasscheck__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">other</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="s1">'_is_protocol'</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="ow">not</span> <span class="n">_allow_reckless_class_checks</span><span class="p">()</span>
|
|
<span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="s1">'_is_runtime_protocol'</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
|
|
<span class="n">_type_check_issubclass_arg_1</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s2">"Instance and class checks can only be used with "</span>
|
|
<span class="s2">"@runtime_checkable protocols"</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="c1"># this attribute is set by @runtime_checkable:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">__non_callable_proto_members__</span>
|
|
<span class="ow">and</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"__subclasshook__"</span><span class="p">)</span> <span class="ow">is</span> <span class="n">_proto_hook</span>
|
|
<span class="p">):</span>
|
|
<span class="n">_type_check_issubclass_arg_1</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
|
|
<span class="n">non_method_attrs</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">__non_callable_proto_members__</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s2">"Protocols with non-method members don't support issubclass()."</span>
|
|
<span class="sa">f</span><span class="s2">" Non-method members: </span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">non_method_attrs</span><span class="p">)[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="si">}</span><span class="s2">."</span>
|
|
<span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_abc_subclasscheck</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">other</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__instancecheck__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span>
|
|
<span class="c1"># We need this method for situations where attributes are</span>
|
|
<span class="c1"># assigned in __init__.</span>
|
|
<span class="k">if</span> <span class="bp">cls</span> <span class="ow">is</span> <span class="n">Protocol</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="nb">type</span><span class="o">.</span><span class="fm">__instancecheck__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">instance</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="s2">"_is_protocol"</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
|
|
<span class="c1"># i.e., it's a concrete subclass of a protocol</span>
|
|
<span class="k">return</span> <span class="n">_abc_instancecheck</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">instance</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="ow">not</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="s1">'_is_runtime_protocol'</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span> <span class="ow">and</span>
|
|
<span class="ow">not</span> <span class="n">_allow_reckless_class_checks</span><span class="p">()</span>
|
|
<span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Instance and class checks can only be used with"</span>
|
|
<span class="s2">" @runtime_checkable protocols"</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">_abc_instancecheck</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
|
|
<span class="n">getattr_static</span> <span class="o">=</span> <span class="n">_lazy_load_getattr_static</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__protocol_attrs__</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">val</span> <span class="o">=</span> <span class="n">getattr_static</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="n">attr</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">break</span>
|
|
<span class="c1"># this attribute is set by @runtime_checkable:</span>
|
|
<span class="k">if</span> <span class="n">val</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">attr</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__non_callable_proto_members__</span><span class="p">:</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_proto_hook</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'_is_protocol'</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__protocol_attrs__</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">other</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">:</span>
|
|
<span class="c1"># Check if the members appears in the class dictionary...</span>
|
|
<span class="k">if</span> <span class="n">attr</span> <span class="ow">in</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="n">attr</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
<span class="k">break</span>
|
|
|
|
<span class="c1"># ...or in annotations, if it is a sub-protocol.</span>
|
|
<span class="n">annotations</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="s1">'__annotations__'</span><span class="p">,</span> <span class="p">{})</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">annotations</span><span class="p">,</span> <span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Mapping</span><span class="p">)</span> <span class="ow">and</span>
|
|
<span class="n">attr</span> <span class="ow">in</span> <span class="n">annotations</span> <span class="ow">and</span>
|
|
<span class="nb">issubclass</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Generic</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="s1">'_is_protocol'</span><span class="p">,</span> <span class="kc">False</span><span class="p">)):</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">Protocol</span><span class="p">(</span><span class="n">Generic</span><span class="p">,</span> <span class="n">metaclass</span><span class="o">=</span><span class="n">_ProtocolMeta</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Base class for protocol classes.</span>
|
|
|
|
<span class="sd"> Protocol classes are defined as::</span>
|
|
|
|
<span class="sd"> class Proto(Protocol):</span>
|
|
<span class="sd"> def meth(self) -> int:</span>
|
|
<span class="sd"> ...</span>
|
|
|
|
<span class="sd"> Such classes are primarily used with static type checkers that recognize</span>
|
|
<span class="sd"> structural subtyping (static duck-typing).</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> class C:</span>
|
|
<span class="sd"> def meth(self) -> int:</span>
|
|
<span class="sd"> return 0</span>
|
|
|
|
<span class="sd"> def func(x: Proto) -> int:</span>
|
|
<span class="sd"> return x.meth()</span>
|
|
|
|
<span class="sd"> func(C()) # Passes static type check</span>
|
|
|
|
<span class="sd"> See PEP 544 for details. Protocol classes decorated with</span>
|
|
<span class="sd"> @typing.runtime_checkable act as simple-minded runtime protocols that check</span>
|
|
<span class="sd"> only the presence of given attributes, ignoring their type signatures.</span>
|
|
<span class="sd"> Protocol classes can be generic, they are defined as::</span>
|
|
|
|
<span class="sd"> class GenProto[T](Protocol):</span>
|
|
<span class="sd"> def meth(self) -> T:</span>
|
|
<span class="sd"> ...</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
<span class="n">_is_protocol</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="n">_is_runtime_protocol</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__init_subclass__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__init_subclass__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Determine if this is a protocol or a concrete subclass.</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'_is_protocol'</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_is_protocol</span> <span class="o">=</span> <span class="nb">any</span><span class="p">(</span><span class="n">b</span> <span class="ow">is</span> <span class="n">Protocol</span> <span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__bases__</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Set (or override) the protocol subclass hook.</span>
|
|
<span class="k">if</span> <span class="s1">'__subclasshook__'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">__subclasshook__</span> <span class="o">=</span> <span class="n">_proto_hook</span>
|
|
|
|
<span class="c1"># Prohibit instantiation for protocol classes</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_is_protocol</span> <span class="ow">and</span> <span class="bp">cls</span><span class="o">.</span><span class="fm">__init__</span> <span class="ow">is</span> <span class="n">Protocol</span><span class="o">.</span><span class="fm">__init__</span><span class="p">:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="fm">__init__</span> <span class="o">=</span> <span class="n">_no_init_or_replace_init</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_AnnotatedAlias</span><span class="p">(</span><span class="n">_NotIterable</span><span class="p">,</span> <span class="n">_GenericAlias</span><span class="p">,</span> <span class="n">_root</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Runtime representation of an annotated type.</span>
|
|
|
|
<span class="sd"> At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't'</span>
|
|
<span class="sd"> with extra annotations. The alias behaves like a normal typing alias.</span>
|
|
<span class="sd"> Instantiating is the same as instantiating the underlying type; binding</span>
|
|
<span class="sd"> it to types is also the same.</span>
|
|
|
|
<span class="sd"> The metadata itself is stored in a '__metadata__' attribute as a tuple.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">origin</span><span class="p">,</span> <span class="n">metadata</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">origin</span><span class="p">,</span> <span class="n">_AnnotatedAlias</span><span class="p">):</span>
|
|
<span class="n">metadata</span> <span class="o">=</span> <span class="n">origin</span><span class="o">.</span><span class="n">__metadata__</span> <span class="o">+</span> <span class="n">metadata</span>
|
|
<span class="n">origin</span> <span class="o">=</span> <span class="n">origin</span><span class="o">.</span><span class="n">__origin__</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">origin</span><span class="p">,</span> <span class="n">origin</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'Annotated'</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__metadata__</span> <span class="o">=</span> <span class="n">metadata</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">copy_with</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
|
|
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">params</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
|
|
<span class="n">new_type</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="n">_AnnotatedAlias</span><span class="p">(</span><span class="n">new_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">__metadata__</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="s2">"typing.Annotated[</span><span class="si">{}</span><span class="s2">, </span><span class="si">{}</span><span class="s2">]"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
|
<span class="n">_type_repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">),</span>
|
|
<span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">__metadata__</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">operator</span><span class="o">.</span><span class="n">getitem</span><span class="p">,</span> <span class="p">(</span>
|
|
<span class="n">Annotated</span><span class="p">,</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,)</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">__metadata__</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">_AnnotatedAlias</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">__origin__</span>
|
|
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">__metadata__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">__metadata__</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">hash</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">__metadata__</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">{</span><span class="s1">'__name__'</span><span class="p">,</span> <span class="s1">'__qualname__'</span><span class="p">}:</span>
|
|
<span class="k">return</span> <span class="s1">'Annotated'</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__getattr__</span><span class="p">(</span><span class="n">attr</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__mro_entries__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,)</span>
|
|
|
|
|
|
<span class="nd">@_TypedCacheSpecialForm</span>
|
|
<span class="nd">@_tp_cache</span><span class="p">(</span><span class="n">typed</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">Annotated</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">params</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Add context-specific metadata to a type.</span>
|
|
|
|
<span class="sd"> Example: Annotated[int, runtime_check.Unsigned] indicates to the</span>
|
|
<span class="sd"> hypothetical runtime_check module that this type is an unsigned int.</span>
|
|
<span class="sd"> Every other consumer of this type can ignore this metadata and treat</span>
|
|
<span class="sd"> this type as int.</span>
|
|
|
|
<span class="sd"> The first argument to Annotated must be a valid type.</span>
|
|
|
|
<span class="sd"> Details:</span>
|
|
|
|
<span class="sd"> - It's an error to call `Annotated` with less than two arguments.</span>
|
|
<span class="sd"> - Access the metadata via the ``__metadata__`` attribute::</span>
|
|
|
|
<span class="sd"> assert Annotated[int, '$'].__metadata__ == ('$',)</span>
|
|
|
|
<span class="sd"> - Nested Annotated types are flattened::</span>
|
|
|
|
<span class="sd"> assert Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3]</span>
|
|
|
|
<span class="sd"> - Instantiating an annotated type is equivalent to instantiating the</span>
|
|
<span class="sd"> underlying type::</span>
|
|
|
|
<span class="sd"> assert Annotated[C, Ann1](5) == C(5)</span>
|
|
|
|
<span class="sd"> - Annotated can be used as a generic type alias::</span>
|
|
|
|
<span class="sd"> type Optimized[T] = Annotated[T, runtime.Optimize()]</span>
|
|
<span class="sd"> # type checker will treat Optimized[int]</span>
|
|
<span class="sd"> # as equivalent to Annotated[int, runtime.Optimize()]</span>
|
|
|
|
<span class="sd"> type OptimizedList[T] = Annotated[list[T], runtime.Optimize()]</span>
|
|
<span class="sd"> # type checker will treat OptimizedList[int]</span>
|
|
<span class="sd"> # as equivalent to Annotated[list[int], runtime.Optimize()]</span>
|
|
|
|
<span class="sd"> - Annotated cannot be used with an unpacked TypeVarTuple::</span>
|
|
|
|
<span class="sd"> type Variadic[*Ts] = Annotated[*Ts, Ann1] # NOT valid</span>
|
|
|
|
<span class="sd"> This would be equivalent to::</span>
|
|
|
|
<span class="sd"> Annotated[T1, T2, T3, ..., Ann1]</span>
|
|
|
|
<span class="sd"> where T1, T2 etc. are TypeVars, which would be invalid, because</span>
|
|
<span class="sd"> only one type should be passed to Annotated.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">params</span><span class="p">)</span> <span class="o"><</span> <span class="mi">2</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Annotated[...] should be used "</span>
|
|
<span class="s2">"with at least two arguments (a type and an "</span>
|
|
<span class="s2">"annotation)."</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">_is_unpacked_typevartuple</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Annotated[...] should not be used with an "</span>
|
|
<span class="s2">"unpacked TypeVarTuple"</span><span class="p">)</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s2">"Annotated[t, ...]: t must be a type."</span>
|
|
<span class="n">origin</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">msg</span><span class="p">,</span> <span class="n">allow_special_forms</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="n">metadata</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
|
|
<span class="k">return</span> <span class="n">_AnnotatedAlias</span><span class="p">(</span><span class="n">origin</span><span class="p">,</span> <span class="n">metadata</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">runtime_checkable</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Mark a protocol class as a runtime protocol.</span>
|
|
|
|
<span class="sd"> Such protocol can be used with isinstance() and issubclass().</span>
|
|
<span class="sd"> Raise TypeError if applied to a non-protocol class.</span>
|
|
<span class="sd"> This allows a simple-minded structural check very similar to</span>
|
|
<span class="sd"> one trick ponies in collections.abc such as Iterable.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> @runtime_checkable</span>
|
|
<span class="sd"> class Closable(Protocol):</span>
|
|
<span class="sd"> def close(self): ...</span>
|
|
|
|
<span class="sd"> assert isinstance(open('/some/file'), Closable)</span>
|
|
|
|
<span class="sd"> Warning: this will check only the presence of the required methods,</span>
|
|
<span class="sd"> not their type signatures!</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">Generic</span><span class="p">)</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="s1">'_is_protocol'</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'@runtime_checkable can be only applied to protocol classes,'</span>
|
|
<span class="s1">' got </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="bp">cls</span><span class="p">)</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_is_runtime_protocol</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="c1"># PEP 544 prohibits using issubclass()</span>
|
|
<span class="c1"># with protocols that have non-method members.</span>
|
|
<span class="c1"># See gh-113320 for why we compute this attribute here,</span>
|
|
<span class="c1"># rather than in `_ProtocolMeta.__init__`</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">__non_callable_proto_members__</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__protocol_attrs__</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">is_callable</span> <span class="o">=</span> <span class="nb">callable</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="kc">None</span><span class="p">))</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Failed to determine whether protocol member </span><span class="si">{</span><span class="n">attr</span><span class="si">!r}</span><span class="s2"> "</span>
|
|
<span class="s2">"is a method member"</span>
|
|
<span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">is_callable</span><span class="p">:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">__non_callable_proto_members__</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">attr</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="bp">cls</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">cast</span><span class="p">(</span><span class="n">typ</span><span class="p">,</span> <span class="n">val</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Cast a value to a type.</span>
|
|
|
|
<span class="sd"> This returns the value unchanged. To the type checker this</span>
|
|
<span class="sd"> signals that the return value has the designated type, but at</span>
|
|
<span class="sd"> runtime we intentionally don't check anything (we want this</span>
|
|
<span class="sd"> to be as fast as possible).</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">val</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assert_type</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">typ</span><span class="p">,</span> <span class="o">/</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Ask a static type checker to confirm that the value is of the given type.</span>
|
|
|
|
<span class="sd"> At runtime this does nothing: it returns the first argument unchanged with no</span>
|
|
<span class="sd"> checks or side effects, no matter the actual type of the argument.</span>
|
|
|
|
<span class="sd"> When a static type checker encounters a call to assert_type(), it</span>
|
|
<span class="sd"> emits an error if the value is not of the specified type::</span>
|
|
|
|
<span class="sd"> def greet(name: str) -> None:</span>
|
|
<span class="sd"> assert_type(name, str) # OK</span>
|
|
<span class="sd"> assert_type(name, int) # type checker error</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">val</span>
|
|
|
|
|
|
<span class="n">_allowed_types</span> <span class="o">=</span> <span class="p">(</span><span class="n">types</span><span class="o">.</span><span class="n">FunctionType</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">BuiltinFunctionType</span><span class="p">,</span>
|
|
<span class="n">types</span><span class="o">.</span><span class="n">MethodType</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">ModuleType</span><span class="p">,</span>
|
|
<span class="n">WrapperDescriptorType</span><span class="p">,</span> <span class="n">MethodWrapperType</span><span class="p">,</span> <span class="n">MethodDescriptorType</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_type_hints</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">globalns</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">localns</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">include_extras</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return type hints for an object.</span>
|
|
|
|
<span class="sd"> This is often the same as obj.__annotations__, but it handles</span>
|
|
<span class="sd"> forward references encoded as string literals and recursively replaces all</span>
|
|
<span class="sd"> 'Annotated[T, ...]' with 'T' (unless 'include_extras=True').</span>
|
|
|
|
<span class="sd"> The argument may be a module, class, method, or function. The annotations</span>
|
|
<span class="sd"> are returned as a dictionary. For classes, annotations include also</span>
|
|
<span class="sd"> inherited members.</span>
|
|
|
|
<span class="sd"> TypeError is raised if the argument is not of a type that can contain</span>
|
|
<span class="sd"> annotations, and an empty dictionary is returned if no annotations are</span>
|
|
<span class="sd"> present.</span>
|
|
|
|
<span class="sd"> BEWARE -- the behavior of globalns and localns is counterintuitive</span>
|
|
<span class="sd"> (unless you are familiar with how eval() and exec() work). The</span>
|
|
<span class="sd"> search order is locals first, then globals.</span>
|
|
|
|
<span class="sd"> - If no dict arguments are passed, an attempt is made to use the</span>
|
|
<span class="sd"> globals from obj (or the respective module's globals for classes),</span>
|
|
<span class="sd"> and these are also used as the locals. If the object does not appear</span>
|
|
<span class="sd"> to have globals, an empty dictionary is used. For classes, the search</span>
|
|
<span class="sd"> order is globals first then locals.</span>
|
|
|
|
<span class="sd"> - If one dict argument is passed, it is used for both globals and</span>
|
|
<span class="sd"> locals.</span>
|
|
|
|
<span class="sd"> - If two dict arguments are passed, they specify globals and</span>
|
|
<span class="sd"> locals, respectively.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__no_type_check__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="p">{}</span>
|
|
<span class="c1"># Classes require a special treatment.</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="n">hints</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">globalns</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">base_globals</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">base</span><span class="o">.</span><span class="vm">__module__</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span> <span class="s1">'__dict__'</span><span class="p">,</span> <span class="p">{})</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">base_globals</span> <span class="o">=</span> <span class="n">globalns</span>
|
|
<span class="n">ann</span> <span class="o">=</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__annotations__'</span><span class="p">,</span> <span class="p">{})</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">ann</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">GetSetDescriptorType</span><span class="p">):</span>
|
|
<span class="n">ann</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">base_locals</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="nb">vars</span><span class="p">(</span><span class="n">base</span><span class="p">))</span> <span class="k">if</span> <span class="n">localns</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">localns</span>
|
|
<span class="k">if</span> <span class="n">localns</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">globalns</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># This is surprising, but required. Before Python 3.10,</span>
|
|
<span class="c1"># get_type_hints only evaluated the globalns of</span>
|
|
<span class="c1"># a class. To maintain backwards compatibility, we reverse</span>
|
|
<span class="c1"># the globalns and localns order so that eval() looks into</span>
|
|
<span class="c1"># *base_globals* first rather than *base_locals*.</span>
|
|
<span class="c1"># This only affects ForwardRefs.</span>
|
|
<span class="n">base_globals</span><span class="p">,</span> <span class="n">base_locals</span> <span class="o">=</span> <span class="n">base_locals</span><span class="p">,</span> <span class="n">base_globals</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">ann</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">ForwardRef</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">is_argument</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">is_class</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">_eval_type</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">base_globals</span><span class="p">,</span> <span class="n">base_locals</span><span class="p">,</span> <span class="n">base</span><span class="o">.</span><span class="n">__type_params__</span><span class="p">)</span>
|
|
<span class="n">hints</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="k">return</span> <span class="n">hints</span> <span class="k">if</span> <span class="n">include_extras</span> <span class="k">else</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">_strip_annotations</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">hints</span><span class="o">.</span><span class="n">items</span><span class="p">()}</span>
|
|
|
|
<span class="k">if</span> <span class="n">globalns</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">ModuleType</span><span class="p">):</span>
|
|
<span class="n">globalns</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">nsobj</span> <span class="o">=</span> <span class="n">obj</span>
|
|
<span class="c1"># Find globalns for the unwrapped object.</span>
|
|
<span class="k">while</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">nsobj</span><span class="p">,</span> <span class="s1">'__wrapped__'</span><span class="p">):</span>
|
|
<span class="n">nsobj</span> <span class="o">=</span> <span class="n">nsobj</span><span class="o">.</span><span class="n">__wrapped__</span>
|
|
<span class="n">globalns</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">nsobj</span><span class="p">,</span> <span class="s1">'__globals__'</span><span class="p">,</span> <span class="p">{})</span>
|
|
<span class="k">if</span> <span class="n">localns</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">localns</span> <span class="o">=</span> <span class="n">globalns</span>
|
|
<span class="k">elif</span> <span class="n">localns</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">localns</span> <span class="o">=</span> <span class="n">globalns</span>
|
|
<span class="n">hints</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__annotations__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">hints</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># Return empty annotations for something that _could_ have them.</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">_allowed_types</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="p">{}</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'</span><span class="si">{!r}</span><span class="s1"> is not a module, class, method, '</span>
|
|
<span class="s1">'or function.'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
|
|
<span class="n">hints</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">hints</span><span class="p">)</span>
|
|
<span class="n">type_params</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s2">"__type_params__"</span><span class="p">,</span> <span class="p">())</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">hints</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="c1"># class-level forward refs were handled above, this must be either</span>
|
|
<span class="c1"># a module-level annotation or a function argument annotation</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">ForwardRef</span><span class="p">(</span>
|
|
<span class="n">value</span><span class="p">,</span>
|
|
<span class="n">is_argument</span><span class="o">=</span><span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">ModuleType</span><span class="p">),</span>
|
|
<span class="n">is_class</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="n">hints</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">_eval_type</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">globalns</span><span class="p">,</span> <span class="n">localns</span><span class="p">,</span> <span class="n">type_params</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">hints</span> <span class="k">if</span> <span class="n">include_extras</span> <span class="k">else</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">_strip_annotations</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">hints</span><span class="o">.</span><span class="n">items</span><span class="p">()}</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_strip_annotations</span><span class="p">(</span><span class="n">t</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Strip the annotations from a given type."""</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">_AnnotatedAlias</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">_strip_annotations</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">__origin__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="s2">"__origin__"</span><span class="p">)</span> <span class="ow">and</span> <span class="n">t</span><span class="o">.</span><span class="n">__origin__</span> <span class="ow">in</span> <span class="p">(</span><span class="n">Required</span><span class="p">,</span> <span class="n">NotRequired</span><span class="p">,</span> <span class="n">ReadOnly</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">_strip_annotations</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">__args__</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">_GenericAlias</span><span class="p">):</span>
|
|
<span class="n">stripped_args</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_strip_annotations</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">t</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">stripped_args</span> <span class="o">==</span> <span class="n">t</span><span class="o">.</span><span class="n">__args__</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">t</span>
|
|
<span class="k">return</span> <span class="n">t</span><span class="o">.</span><span class="n">copy_with</span><span class="p">(</span><span class="n">stripped_args</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">GenericAlias</span><span class="p">):</span>
|
|
<span class="n">stripped_args</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_strip_annotations</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">t</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">stripped_args</span> <span class="o">==</span> <span class="n">t</span><span class="o">.</span><span class="n">__args__</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">t</span>
|
|
<span class="k">return</span> <span class="n">GenericAlias</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,</span> <span class="n">stripped_args</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">UnionType</span><span class="p">):</span>
|
|
<span class="n">stripped_args</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_strip_annotations</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">t</span><span class="o">.</span><span class="n">__args__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">stripped_args</span> <span class="o">==</span> <span class="n">t</span><span class="o">.</span><span class="n">__args__</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">t</span>
|
|
<span class="k">return</span> <span class="n">functools</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="n">operator</span><span class="o">.</span><span class="n">or_</span><span class="p">,</span> <span class="n">stripped_args</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">t</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_origin</span><span class="p">(</span><span class="n">tp</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get the unsubscripted version of a type.</span>
|
|
|
|
<span class="sd"> This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar,</span>
|
|
<span class="sd"> Annotated, and others. Return None for unsupported types.</span>
|
|
|
|
<span class="sd"> Examples::</span>
|
|
|
|
<span class="sd"> >>> P = ParamSpec('P')</span>
|
|
<span class="sd"> >>> assert get_origin(Literal[42]) is Literal</span>
|
|
<span class="sd"> >>> assert get_origin(int) is None</span>
|
|
<span class="sd"> >>> assert get_origin(ClassVar[int]) is ClassVar</span>
|
|
<span class="sd"> >>> assert get_origin(Generic) is Generic</span>
|
|
<span class="sd"> >>> assert get_origin(Generic[T]) is Generic</span>
|
|
<span class="sd"> >>> assert get_origin(Union[T, int]) is Union</span>
|
|
<span class="sd"> >>> assert get_origin(List[Tuple[T, T]][int]) is list</span>
|
|
<span class="sd"> >>> assert get_origin(P.args) is P</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="n">_AnnotatedAlias</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Annotated</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="p">(</span><span class="n">_BaseGenericAlias</span><span class="p">,</span> <span class="n">GenericAlias</span><span class="p">,</span>
|
|
<span class="n">ParamSpecArgs</span><span class="p">,</span> <span class="n">ParamSpecKwargs</span><span class="p">)):</span>
|
|
<span class="k">return</span> <span class="n">tp</span><span class="o">.</span><span class="n">__origin__</span>
|
|
<span class="k">if</span> <span class="n">tp</span> <span class="ow">is</span> <span class="n">Generic</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">Generic</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">UnionType</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">types</span><span class="o">.</span><span class="n">UnionType</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_args</span><span class="p">(</span><span class="n">tp</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get type arguments with all substitutions performed.</span>
|
|
|
|
<span class="sd"> For unions, basic simplifications used by Union constructor are performed.</span>
|
|
|
|
<span class="sd"> Examples::</span>
|
|
|
|
<span class="sd"> >>> T = TypeVar('T')</span>
|
|
<span class="sd"> >>> assert get_args(Dict[str, int]) == (str, int)</span>
|
|
<span class="sd"> >>> assert get_args(int) == ()</span>
|
|
<span class="sd"> >>> assert get_args(Union[int, Union[T, int], str][int]) == (int, str)</span>
|
|
<span class="sd"> >>> assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])</span>
|
|
<span class="sd"> >>> assert get_args(Callable[[], T][int]) == ([], int)</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="n">_AnnotatedAlias</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="n">tp</span><span class="o">.</span><span class="n">__origin__</span><span class="p">,)</span> <span class="o">+</span> <span class="n">tp</span><span class="o">.</span><span class="n">__metadata__</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="p">(</span><span class="n">_GenericAlias</span><span class="p">,</span> <span class="n">GenericAlias</span><span class="p">)):</span>
|
|
<span class="n">res</span> <span class="o">=</span> <span class="n">tp</span><span class="o">.</span><span class="n">__args__</span>
|
|
<span class="k">if</span> <span class="n">_should_unflatten_callable_args</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="n">res</span><span class="p">):</span>
|
|
<span class="n">res</span> <span class="o">=</span> <span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">res</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]),</span> <span class="n">res</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
|
|
<span class="k">return</span> <span class="n">res</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">UnionType</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">tp</span><span class="o">.</span><span class="n">__args__</span>
|
|
<span class="k">return</span> <span class="p">()</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">is_typeddict</span><span class="p">(</span><span class="n">tp</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Check if an annotation is a TypedDict class.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> >>> from typing import TypedDict</span>
|
|
<span class="sd"> >>> class Film(TypedDict):</span>
|
|
<span class="sd"> ... title: str</span>
|
|
<span class="sd"> ... year: int</span>
|
|
<span class="sd"> ...</span>
|
|
<span class="sd"> >>> is_typeddict(Film)</span>
|
|
<span class="sd"> True</span>
|
|
<span class="sd"> >>> is_typeddict(dict)</span>
|
|
<span class="sd"> False</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="n">_TypedDictMeta</span><span class="p">)</span>
|
|
|
|
|
|
<span class="n">_ASSERT_NEVER_REPR_MAX_LENGTH</span> <span class="o">=</span> <span class="mi">100</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assert_never</span><span class="p">(</span><span class="n">arg</span><span class="p">:</span> <span class="n">Never</span><span class="p">,</span> <span class="o">/</span><span class="p">)</span> <span class="o">-></span> <span class="n">Never</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Statically assert that a line of code is unreachable.</span>
|
|
|
|
<span class="sd"> Example::</span>
|
|
|
|
<span class="sd"> def int_or_str(arg: int | str) -> None:</span>
|
|
<span class="sd"> match arg:</span>
|
|
<span class="sd"> case int():</span>
|
|
<span class="sd"> print("It's an int")</span>
|
|
<span class="sd"> case str():</span>
|
|
<span class="sd"> print("It's a str")</span>
|
|
<span class="sd"> case _:</span>
|
|
<span class="sd"> assert_never(arg)</span>
|
|
|
|
<span class="sd"> If a type checker finds that a call to assert_never() is</span>
|
|
<span class="sd"> reachable, it will emit an error.</span>
|
|
|
|
<span class="sd"> At runtime, this throws an exception when called.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="nb">repr</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="o">></span> <span class="n">_ASSERT_NEVER_REPR_MAX_LENGTH</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="p">[:</span><span class="n">_ASSERT_NEVER_REPR_MAX_LENGTH</span><span class="p">]</span> <span class="o">+</span> <span class="s1">'...'</span>
|
|
<span class="k">raise</span> <span class="ne">AssertionError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Expected code to be unreachable, but got: </span><span class="si">{</span><span class="n">value</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">no_type_check</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Decorator to indicate that annotations are not type hints.</span>
|
|
|
|
<span class="sd"> The argument must be a class or function; if it is a class, it</span>
|
|
<span class="sd"> applies recursively to all methods and classes defined in that class</span>
|
|
<span class="sd"> (but not to methods defined in its superclasses or subclasses).</span>
|
|
|
|
<span class="sd"> This mutates the function(s) or class(es) in place.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="nb">dir</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__qualname__'</span><span class="p">)</span>
|
|
<span class="ow">or</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__qualname__</span> <span class="o">!=</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">arg</span><span class="o">.</span><span class="vm">__qualname__</span><span class="si">}</span><span class="s1">.</span><span class="si">{</span><span class="n">obj</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s1">'</span>
|
|
<span class="ow">or</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="o">!=</span> <span class="n">arg</span><span class="o">.</span><span class="vm">__module__</span>
|
|
<span class="p">):</span>
|
|
<span class="c1"># We only modify objects that are defined in this type directly.</span>
|
|
<span class="c1"># If classes / methods are nested in multiple layers,</span>
|
|
<span class="c1"># we will modify them when processing their direct holders.</span>
|
|
<span class="k">continue</span>
|
|
<span class="c1"># Instance, class, and static methods:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">FunctionType</span><span class="p">):</span>
|
|
<span class="n">obj</span><span class="o">.</span><span class="n">__no_type_check__</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">MethodType</span><span class="p">):</span>
|
|
<span class="n">obj</span><span class="o">.</span><span class="vm">__func__</span><span class="o">.</span><span class="n">__no_type_check__</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="c1"># Nested types:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="n">no_type_check</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">arg</span><span class="o">.</span><span class="n">__no_type_check__</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> <span class="c1"># built-in classes</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">return</span> <span class="n">arg</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">no_type_check_decorator</span><span class="p">(</span><span class="n">decorator</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Decorator to give another decorator the @no_type_check effect.</span>
|
|
|
|
<span class="sd"> This wraps the decorator with something that wraps the decorated</span>
|
|
<span class="sd"> function in @no_type_check.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">warnings</span>
|
|
<span class="n">warnings</span><span class="o">.</span><span class="n">_deprecated</span><span class="p">(</span><span class="s2">"typing.no_type_check_decorator"</span><span class="p">,</span> <span class="n">remove</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">15</span><span class="p">))</span>
|
|
<span class="nd">@functools</span><span class="o">.</span><span class="n">wraps</span><span class="p">(</span><span class="n">decorator</span><span class="p">)</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">wrapped_decorator</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span>
|
|
<span class="n">func</span> <span class="o">=</span> <span class="n">decorator</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">)</span>
|
|
<span class="n">func</span> <span class="o">=</span> <span class="n">no_type_check</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">func</span>
|
|
|
|
<span class="k">return</span> <span class="n">wrapped_decorator</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_overload_dummy</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Helper for @overload to raise when called."""</span>
|
|
<span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span>
|
|
<span class="s2">"You should not call an overloaded function. "</span>
|
|
<span class="s2">"A series of @overload-decorated functions "</span>
|
|
<span class="s2">"outside a stub module should always be followed "</span>
|
|
<span class="s2">"by an implementation that is not @overload-ed."</span><span class="p">)</span>
|
|
|
|
|
|
<span class="c1"># {module: {qualname: {firstlineno: func}}}</span>
|
|
<span class="n">_overload_registry</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="n">functools</span><span class="o">.</span><span class="n">partial</span><span class="p">(</span><span class="n">defaultdict</span><span class="p">,</span> <span class="nb">dict</span><span class="p">))</span>
|
|
|
|
|
|
<div class="viewcode-block" id="overload">
|
|
<a class="viewcode-back" href="../api/evennia.utils.utils.html#evennia.utils.overload">[docs]</a>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">overload</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Decorator for overloaded functions/methods.</span>
|
|
|
|
<span class="sd"> In a stub file, place two or more stub definitions for the same</span>
|
|
<span class="sd"> function in a row, each decorated with @overload.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> @overload</span>
|
|
<span class="sd"> def utf8(value: None) -> None: ...</span>
|
|
<span class="sd"> @overload</span>
|
|
<span class="sd"> def utf8(value: bytes) -> bytes: ...</span>
|
|
<span class="sd"> @overload</span>
|
|
<span class="sd"> def utf8(value: str) -> bytes: ...</span>
|
|
|
|
<span class="sd"> In a non-stub file (i.e. a regular .py file), do the same but</span>
|
|
<span class="sd"> follow it with an implementation. The implementation should *not*</span>
|
|
<span class="sd"> be decorated with @overload::</span>
|
|
|
|
<span class="sd"> @overload</span>
|
|
<span class="sd"> def utf8(value: None) -> None: ...</span>
|
|
<span class="sd"> @overload</span>
|
|
<span class="sd"> def utf8(value: bytes) -> bytes: ...</span>
|
|
<span class="sd"> @overload</span>
|
|
<span class="sd"> def utf8(value: str) -> bytes: ...</span>
|
|
<span class="sd"> def utf8(value):</span>
|
|
<span class="sd"> ... # implementation goes here</span>
|
|
|
|
<span class="sd"> The overloads for a function can be retrieved at runtime using the</span>
|
|
<span class="sd"> get_overloads() function.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># classmethod and staticmethod</span>
|
|
<span class="n">f</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s2">"__func__"</span><span class="p">,</span> <span class="n">func</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">_overload_registry</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="vm">__module__</span><span class="p">][</span><span class="n">f</span><span class="o">.</span><span class="vm">__qualname__</span><span class="p">][</span><span class="n">f</span><span class="o">.</span><span class="vm">__code__</span><span class="o">.</span><span class="n">co_firstlineno</span><span class="p">]</span> <span class="o">=</span> <span class="n">func</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="c1"># Not a normal function; ignore.</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">return</span> <span class="n">_overload_dummy</span></div>
|
|
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_overloads</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return all defined overloads for *func* as a sequence."""</span>
|
|
<span class="c1"># classmethod and staticmethod</span>
|
|
<span class="n">f</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s2">"__func__"</span><span class="p">,</span> <span class="n">func</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="vm">__module__</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">_overload_registry</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="p">[]</span>
|
|
<span class="n">mod_dict</span> <span class="o">=</span> <span class="n">_overload_registry</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="vm">__module__</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="vm">__qualname__</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">mod_dict</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="p">[]</span>
|
|
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">mod_dict</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="vm">__qualname__</span><span class="p">]</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">clear_overloads</span><span class="p">():</span>
|
|
<span class="w"> </span><span class="sd">"""Clear all overloads in the registry."""</span>
|
|
<span class="n">_overload_registry</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">final</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Decorator to indicate final methods and final classes.</span>
|
|
|
|
<span class="sd"> Use this decorator to indicate to type checkers that the decorated</span>
|
|
<span class="sd"> method cannot be overridden, and decorated class cannot be subclassed.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> class Base:</span>
|
|
<span class="sd"> @final</span>
|
|
<span class="sd"> def done(self) -> None:</span>
|
|
<span class="sd"> ...</span>
|
|
<span class="sd"> class Sub(Base):</span>
|
|
<span class="sd"> def done(self) -> None: # Error reported by type checker</span>
|
|
<span class="sd"> ...</span>
|
|
|
|
<span class="sd"> @final</span>
|
|
<span class="sd"> class Leaf:</span>
|
|
<span class="sd"> ...</span>
|
|
<span class="sd"> class Other(Leaf): # Error reported by type checker</span>
|
|
<span class="sd"> ...</span>
|
|
|
|
<span class="sd"> There is no runtime checking of these properties. The decorator</span>
|
|
<span class="sd"> attempts to set the ``__final__`` attribute to ``True`` on the decorated</span>
|
|
<span class="sd"> object to allow runtime introspection.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">f</span><span class="o">.</span><span class="n">__final__</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">AttributeError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
|
|
<span class="c1"># Skip the attribute silently if it is not writable.</span>
|
|
<span class="c1"># AttributeError happens if the object has __slots__ or a</span>
|
|
<span class="c1"># read-only property, TypeError if it's a builtin class.</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">return</span> <span class="n">f</span>
|
|
|
|
|
|
<span class="c1"># Some unconstrained type variables. These were initially used by the container types.</span>
|
|
<span class="c1"># They were never meant for export and are now unused, but we keep them around to</span>
|
|
<span class="c1"># avoid breaking compatibility with users who import them.</span>
|
|
<span class="n">T</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s1">'T'</span><span class="p">)</span> <span class="c1"># Any type.</span>
|
|
<span class="n">KT</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s1">'KT'</span><span class="p">)</span> <span class="c1"># Key type.</span>
|
|
<span class="n">VT</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s1">'VT'</span><span class="p">)</span> <span class="c1"># Value type.</span>
|
|
<span class="n">T_co</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s1">'T_co'</span><span class="p">,</span> <span class="n">covariant</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="c1"># Any type covariant containers.</span>
|
|
<span class="n">V_co</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s1">'V_co'</span><span class="p">,</span> <span class="n">covariant</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="c1"># Any type covariant containers.</span>
|
|
<span class="n">VT_co</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s1">'VT_co'</span><span class="p">,</span> <span class="n">covariant</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="c1"># Value type covariant containers.</span>
|
|
<span class="n">T_contra</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s1">'T_contra'</span><span class="p">,</span> <span class="n">contravariant</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="c1"># Ditto contravariant.</span>
|
|
<span class="c1"># Internal type variable used for Type[].</span>
|
|
<span class="n">CT_co</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s1">'CT_co'</span><span class="p">,</span> <span class="n">covariant</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">bound</span><span class="o">=</span><span class="nb">type</span><span class="p">)</span>
|
|
|
|
|
|
<span class="c1"># A useful type variable with constraints. This represents string types.</span>
|
|
<span class="c1"># (This one *is* for export!)</span>
|
|
<span class="n">AnyStr</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s1">'AnyStr'</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span>
|
|
|
|
|
|
<span class="c1"># Various ABCs mimicking those in collections.abc.</span>
|
|
<span class="n">_alias</span> <span class="o">=</span> <span class="n">_SpecialGenericAlias</span>
|
|
|
|
<span class="n">Hashable</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Hashable</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="c1"># Not generic.</span>
|
|
<span class="n">Awaitable</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Awaitable</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">Coroutine</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Coroutine</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
|
<span class="n">AsyncIterable</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">AsyncIterable</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">AsyncIterator</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">AsyncIterator</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">Iterable</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Iterable</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">Iterator</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Iterator</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">Reversible</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Reversible</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">Sized</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Sized</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="c1"># Not generic.</span>
|
|
<span class="n">Container</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Container</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">Collection</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Collection</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">Callable</span> <span class="o">=</span> <span class="n">_CallableType</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Callable</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
|
<span class="n">Callable</span><span class="o">.</span><span class="vm">__doc__</span> <span class="o">=</span> \
|
|
<span class="w"> </span><span class="sd">"""Deprecated alias to collections.abc.Callable.</span>
|
|
|
|
<span class="sd"> Callable[[int], str] signifies a function that takes a single</span>
|
|
<span class="sd"> parameter of type int and returns a str.</span>
|
|
|
|
<span class="sd"> The subscription syntax must always be used with exactly two</span>
|
|
<span class="sd"> values: the argument list and the return type.</span>
|
|
<span class="sd"> The argument list must be a list of types, a ParamSpec,</span>
|
|
<span class="sd"> Concatenate or ellipsis. The return type must be a single type.</span>
|
|
|
|
<span class="sd"> There is no syntax to indicate optional or keyword arguments;</span>
|
|
<span class="sd"> such function types are rarely used as callback types.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">AbstractSet</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Set</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'AbstractSet'</span><span class="p">)</span>
|
|
<span class="n">MutableSet</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">MutableSet</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="c1"># NOTE: Mapping is only covariant in the value type.</span>
|
|
<span class="n">Mapping</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Mapping</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
|
<span class="n">MutableMapping</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">MutableMapping</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
|
<span class="n">Sequence</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Sequence</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">MutableSequence</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">MutableSequence</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">ByteString</span> <span class="o">=</span> <span class="n">_DeprecatedGenericAlias</span><span class="p">(</span>
|
|
<span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">ByteString</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">removal_version</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">14</span><span class="p">)</span> <span class="c1"># Not generic.</span>
|
|
<span class="p">)</span>
|
|
<span class="c1"># Tuple accepts variable number of parameters.</span>
|
|
<span class="n">Tuple</span> <span class="o">=</span> <span class="n">_TupleType</span><span class="p">(</span><span class="nb">tuple</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'Tuple'</span><span class="p">)</span>
|
|
<span class="n">Tuple</span><span class="o">.</span><span class="vm">__doc__</span> <span class="o">=</span> \
|
|
<span class="w"> </span><span class="sd">"""Deprecated alias to builtins.tuple.</span>
|
|
|
|
<span class="sd"> Tuple[X, Y] is the cross-product type of X and Y.</span>
|
|
|
|
<span class="sd"> Example: Tuple[T1, T2] is a tuple of two elements corresponding</span>
|
|
<span class="sd"> to type variables T1 and T2. Tuple[int, float, str] is a tuple</span>
|
|
<span class="sd"> of an int, a float and a string.</span>
|
|
|
|
<span class="sd"> To specify a variable-length tuple of homogeneous type, use Tuple[T, ...].</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">List</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'List'</span><span class="p">)</span>
|
|
<span class="n">Deque</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">deque</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'Deque'</span><span class="p">)</span>
|
|
<span class="n">Set</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="nb">set</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'Set'</span><span class="p">)</span>
|
|
<span class="n">FrozenSet</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="nb">frozenset</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'FrozenSet'</span><span class="p">)</span>
|
|
<span class="n">MappingView</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">MappingView</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">KeysView</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">KeysView</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">ItemsView</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">ItemsView</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
|
<span class="n">ValuesView</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">ValuesView</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">Dict</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="nb">dict</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'Dict'</span><span class="p">)</span>
|
|
<span class="n">DefaultDict</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">defaultdict</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'DefaultDict'</span><span class="p">)</span>
|
|
<span class="n">OrderedDict</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">OrderedDict</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
|
<span class="n">Counter</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">Counter</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">ChainMap</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">ChainMap</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
|
<span class="n">Generator</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Generator</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="p">(</span><span class="n">types</span><span class="o">.</span><span class="n">NoneType</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">NoneType</span><span class="p">))</span>
|
|
<span class="n">AsyncGenerator</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">AsyncGenerator</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="p">(</span><span class="n">types</span><span class="o">.</span><span class="n">NoneType</span><span class="p">,))</span>
|
|
<span class="n">Type</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="nb">type</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">inst</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'Type'</span><span class="p">)</span>
|
|
<span class="n">Type</span><span class="o">.</span><span class="vm">__doc__</span> <span class="o">=</span> \
|
|
<span class="w"> </span><span class="sd">"""Deprecated alias to builtins.type.</span>
|
|
|
|
<span class="sd"> builtins.type or typing.Type can be used to annotate class objects.</span>
|
|
<span class="sd"> For example, suppose we have the following classes::</span>
|
|
|
|
<span class="sd"> class User: ... # Abstract base for User classes</span>
|
|
<span class="sd"> class BasicUser(User): ...</span>
|
|
<span class="sd"> class ProUser(User): ...</span>
|
|
<span class="sd"> class TeamUser(User): ...</span>
|
|
|
|
<span class="sd"> And a function that takes a class argument that's a subclass of</span>
|
|
<span class="sd"> User and returns an instance of the corresponding class::</span>
|
|
|
|
<span class="sd"> def new_user[U](user_class: Type[U]) -> U:</span>
|
|
<span class="sd"> user = user_class()</span>
|
|
<span class="sd"> # (Here we could write the user object to a database)</span>
|
|
<span class="sd"> return user</span>
|
|
|
|
<span class="sd"> joe = new_user(BasicUser)</span>
|
|
|
|
<span class="sd"> At this point the type checker knows that joe has type BasicUser.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
|
|
<span class="nd">@runtime_checkable</span>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">SupportsInt</span><span class="p">(</span><span class="n">Protocol</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""An ABC with one abstract method __int__."""</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__int__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="nd">@runtime_checkable</span>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">SupportsFloat</span><span class="p">(</span><span class="n">Protocol</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""An ABC with one abstract method __float__."""</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__float__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">float</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="nd">@runtime_checkable</span>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">SupportsComplex</span><span class="p">(</span><span class="n">Protocol</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""An ABC with one abstract method __complex__."""</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__complex__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">complex</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="nd">@runtime_checkable</span>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">SupportsBytes</span><span class="p">(</span><span class="n">Protocol</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""An ABC with one abstract method __bytes__."""</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__bytes__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bytes</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="nd">@runtime_checkable</span>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">SupportsIndex</span><span class="p">(</span><span class="n">Protocol</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""An ABC with one abstract method __index__."""</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__index__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="nd">@runtime_checkable</span>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">SupportsAbs</span><span class="p">[</span><span class="n">T</span><span class="p">](</span><span class="n">Protocol</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""An ABC with one abstract method __abs__ that is covariant in its return type."""</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__abs__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">T</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="nd">@runtime_checkable</span>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">SupportsRound</span><span class="p">[</span><span class="n">T</span><span class="p">](</span><span class="n">Protocol</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""An ABC with one abstract method __round__ that is covariant in its return type."""</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__round__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ndigits</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-></span> <span class="n">T</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_make_nmtuple</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">types</span><span class="p">,</span> <span class="n">module</span><span class="p">,</span> <span class="n">defaults</span> <span class="o">=</span> <span class="p">()):</span>
|
|
<span class="n">fields</span> <span class="o">=</span> <span class="p">[</span><span class="n">n</span> <span class="k">for</span> <span class="n">n</span><span class="p">,</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">types</span><span class="p">]</span>
|
|
<span class="n">types</span> <span class="o">=</span> <span class="p">{</span><span class="n">n</span><span class="p">:</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"field </span><span class="si">{</span><span class="n">n</span><span class="si">}</span><span class="s2"> annotation must be a type"</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">n</span><span class="p">,</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">types</span><span class="p">}</span>
|
|
<span class="n">nm_tpl</span> <span class="o">=</span> <span class="n">collections</span><span class="o">.</span><span class="n">namedtuple</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">fields</span><span class="p">,</span>
|
|
<span class="n">defaults</span><span class="o">=</span><span class="n">defaults</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="n">module</span><span class="p">)</span>
|
|
<span class="n">nm_tpl</span><span class="o">.</span><span class="vm">__annotations__</span> <span class="o">=</span> <span class="n">nm_tpl</span><span class="o">.</span><span class="fm">__new__</span><span class="o">.</span><span class="vm">__annotations__</span> <span class="o">=</span> <span class="n">types</span>
|
|
<span class="k">return</span> <span class="n">nm_tpl</span>
|
|
|
|
|
|
<span class="c1"># attributes prohibited to set in NamedTuple class syntax</span>
|
|
<span class="n">_prohibited</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'__new__'</span><span class="p">,</span> <span class="s1">'__init__'</span><span class="p">,</span> <span class="s1">'__slots__'</span><span class="p">,</span> <span class="s1">'__getnewargs__'</span><span class="p">,</span>
|
|
<span class="s1">'_fields'</span><span class="p">,</span> <span class="s1">'_field_defaults'</span><span class="p">,</span>
|
|
<span class="s1">'_make'</span><span class="p">,</span> <span class="s1">'_replace'</span><span class="p">,</span> <span class="s1">'_asdict'</span><span class="p">,</span> <span class="s1">'_source'</span><span class="p">})</span>
|
|
|
|
<span class="n">_special</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'__module__'</span><span class="p">,</span> <span class="s1">'__name__'</span><span class="p">,</span> <span class="s1">'__annotations__'</span><span class="p">})</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">NamedTupleMeta</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">typename</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">ns</span><span class="p">):</span>
|
|
<span class="k">assert</span> <span class="n">_NamedTuple</span> <span class="ow">in</span> <span class="n">bases</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">base</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_NamedTuple</span> <span class="ow">and</span> <span class="n">base</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">Generic</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s1">'can only inherit from a NamedTuple type and Generic'</span><span class="p">)</span>
|
|
<span class="n">bases</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="nb">tuple</span> <span class="k">if</span> <span class="n">base</span> <span class="ow">is</span> <span class="n">_NamedTuple</span> <span class="k">else</span> <span class="n">base</span> <span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">)</span>
|
|
<span class="n">types</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__annotations__'</span><span class="p">,</span> <span class="p">{})</span>
|
|
<span class="n">default_names</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">field_name</span> <span class="ow">in</span> <span class="n">types</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">field_name</span> <span class="ow">in</span> <span class="n">ns</span><span class="p">:</span>
|
|
<span class="n">default_names</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">field_name</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">default_names</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Non-default namedtuple field </span><span class="si">{</span><span class="n">field_name</span><span class="si">}</span><span class="s2"> "</span>
|
|
<span class="sa">f</span><span class="s2">"cannot follow default field"</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="s1">'s'</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nb">len</span><span class="p">(</span><span class="n">default_names</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="s1">''</span><span class="si">}</span><span class="s2"> "</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">default_names</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="n">nm_tpl</span> <span class="o">=</span> <span class="n">_make_nmtuple</span><span class="p">(</span><span class="n">typename</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">items</span><span class="p">(),</span>
|
|
<span class="n">defaults</span><span class="o">=</span><span class="p">[</span><span class="n">ns</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">default_names</span><span class="p">],</span>
|
|
<span class="n">module</span><span class="o">=</span><span class="n">ns</span><span class="p">[</span><span class="s1">'__module__'</span><span class="p">])</span>
|
|
<span class="n">nm_tpl</span><span class="o">.</span><span class="vm">__bases__</span> <span class="o">=</span> <span class="n">bases</span>
|
|
<span class="k">if</span> <span class="n">Generic</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="n">class_getitem</span> <span class="o">=</span> <span class="n">_generic_class_getitem</span>
|
|
<span class="n">nm_tpl</span><span class="o">.</span><span class="n">__class_getitem__</span> <span class="o">=</span> <span class="nb">classmethod</span><span class="p">(</span><span class="n">class_getitem</span><span class="p">)</span>
|
|
<span class="c1"># update from user namespace without overriding special namedtuple attributes</span>
|
|
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">ns</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">_prohibited</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="s2">"Cannot overwrite NamedTuple attribute "</span> <span class="o">+</span> <span class="n">key</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">_special</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">nm_tpl</span><span class="o">.</span><span class="n">_fields</span><span class="p">:</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="n">nm_tpl</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">set_name</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">val</span><span class="p">)</span><span class="o">.</span><span class="n">__set_name__</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">set_name</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">nm_tpl</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">BaseException</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
|
<span class="n">e</span><span class="o">.</span><span class="n">add_note</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Error calling __set_name__ on </span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="n">val</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="si">!r}</span><span class="s2"> "</span>
|
|
<span class="sa">f</span><span class="s2">"instance </span><span class="si">{</span><span class="n">key</span><span class="si">!r}</span><span class="s2"> in </span><span class="si">{</span><span class="n">typename</span><span class="si">!r}</span><span class="s2">"</span>
|
|
<span class="p">)</span>
|
|
<span class="k">raise</span>
|
|
|
|
<span class="k">if</span> <span class="n">Generic</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="n">nm_tpl</span><span class="o">.</span><span class="n">__init_subclass__</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="n">nm_tpl</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">NamedTuple</span><span class="p">(</span><span class="n">typename</span><span class="p">,</span> <span class="n">fields</span><span class="o">=</span><span class="n">_sentinel</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Typed version of namedtuple.</span>
|
|
|
|
<span class="sd"> Usage::</span>
|
|
|
|
<span class="sd"> class Employee(NamedTuple):</span>
|
|
<span class="sd"> name: str</span>
|
|
<span class="sd"> id: int</span>
|
|
|
|
<span class="sd"> This is equivalent to::</span>
|
|
|
|
<span class="sd"> Employee = collections.namedtuple('Employee', ['name', 'id'])</span>
|
|
|
|
<span class="sd"> The resulting class has an extra __annotations__ attribute, giving a</span>
|
|
<span class="sd"> dict that maps field names to types. (The field names are also in</span>
|
|
<span class="sd"> the _fields attribute, which is part of the namedtuple API.)</span>
|
|
<span class="sd"> An alternative equivalent functional syntax is also accepted::</span>
|
|
|
|
<span class="sd"> Employee = NamedTuple('Employee', [('name', str), ('id', int)])</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">fields</span> <span class="ow">is</span> <span class="n">_sentinel</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">kwargs</span><span class="p">:</span>
|
|
<span class="n">deprecated_thing</span> <span class="o">=</span> <span class="s2">"Creating NamedTuple classes using keyword arguments"</span>
|
|
<span class="n">deprecation_msg</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="s2">"</span><span class="si">{name}</span><span class="s2"> is deprecated and will be disallowed in Python </span><span class="si">{remove}</span><span class="s2">. "</span>
|
|
<span class="s2">"Use the class-based or functional syntax instead."</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">deprecated_thing</span> <span class="o">=</span> <span class="s2">"Failing to pass a value for the 'fields' parameter"</span>
|
|
<span class="n">example</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"`</span><span class="si">{</span><span class="n">typename</span><span class="si">}</span><span class="s2"> = NamedTuple(</span><span class="si">{</span><span class="n">typename</span><span class="si">!r}</span><span class="s2">, [])`"</span>
|
|
<span class="n">deprecation_msg</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="s2">"</span><span class="si">{name}</span><span class="s2"> is deprecated and will be disallowed in Python </span><span class="si">{remove}</span><span class="s2">. "</span>
|
|
<span class="s2">"To create a NamedTuple class with 0 fields "</span>
|
|
<span class="s2">"using the functional syntax, "</span>
|
|
<span class="s2">"pass an empty list, e.g. "</span>
|
|
<span class="p">)</span> <span class="o">+</span> <span class="n">example</span> <span class="o">+</span> <span class="s2">"."</span>
|
|
<span class="k">elif</span> <span class="n">fields</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">kwargs</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s2">"Cannot pass `None` as the 'fields' parameter "</span>
|
|
<span class="s2">"and also specify fields using keyword arguments"</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">deprecated_thing</span> <span class="o">=</span> <span class="s2">"Passing `None` as the 'fields' parameter"</span>
|
|
<span class="n">example</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"`</span><span class="si">{</span><span class="n">typename</span><span class="si">}</span><span class="s2"> = NamedTuple(</span><span class="si">{</span><span class="n">typename</span><span class="si">!r}</span><span class="s2">, [])`"</span>
|
|
<span class="n">deprecation_msg</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="s2">"</span><span class="si">{name}</span><span class="s2"> is deprecated and will be disallowed in Python </span><span class="si">{remove}</span><span class="s2">. "</span>
|
|
<span class="s2">"To create a NamedTuple class with 0 fields "</span>
|
|
<span class="s2">"using the functional syntax, "</span>
|
|
<span class="s2">"pass an empty list, e.g. "</span>
|
|
<span class="p">)</span> <span class="o">+</span> <span class="n">example</span> <span class="o">+</span> <span class="s2">"."</span>
|
|
<span class="k">elif</span> <span class="n">kwargs</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Either list of fields or keywords"</span>
|
|
<span class="s2">" can be provided to NamedTuple, not both"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">fields</span> <span class="ow">is</span> <span class="n">_sentinel</span> <span class="ow">or</span> <span class="n">fields</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">warnings</span>
|
|
<span class="n">warnings</span><span class="o">.</span><span class="n">_deprecated</span><span class="p">(</span><span class="n">deprecated_thing</span><span class="p">,</span> <span class="n">message</span><span class="o">=</span><span class="n">deprecation_msg</span><span class="p">,</span> <span class="n">remove</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">15</span><span class="p">))</span>
|
|
<span class="n">fields</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
|
<span class="n">nt</span> <span class="o">=</span> <span class="n">_make_nmtuple</span><span class="p">(</span><span class="n">typename</span><span class="p">,</span> <span class="n">fields</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="n">_caller</span><span class="p">())</span>
|
|
<span class="n">nt</span><span class="o">.</span><span class="n">__orig_bases__</span> <span class="o">=</span> <span class="p">(</span><span class="n">NamedTuple</span><span class="p">,)</span>
|
|
<span class="k">return</span> <span class="n">nt</span>
|
|
|
|
<span class="n">_NamedTuple</span> <span class="o">=</span> <span class="nb">type</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="n">NamedTupleMeta</span><span class="p">,</span> <span class="s1">'NamedTuple'</span><span class="p">,</span> <span class="p">(),</span> <span class="p">{})</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_namedtuple_mro_entries</span><span class="p">(</span><span class="n">bases</span><span class="p">):</span>
|
|
<span class="k">assert</span> <span class="n">NamedTuple</span> <span class="ow">in</span> <span class="n">bases</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="n">_NamedTuple</span><span class="p">,)</span>
|
|
|
|
<span class="n">NamedTuple</span><span class="o">.</span><span class="n">__mro_entries__</span> <span class="o">=</span> <span class="n">_namedtuple_mro_entries</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_get_typeddict_qualifiers</span><span class="p">(</span><span class="n">annotation_type</span><span class="p">):</span>
|
|
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
|
<span class="n">annotation_origin</span> <span class="o">=</span> <span class="n">get_origin</span><span class="p">(</span><span class="n">annotation_type</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">annotation_origin</span> <span class="ow">is</span> <span class="n">Annotated</span><span class="p">:</span>
|
|
<span class="n">annotation_args</span> <span class="o">=</span> <span class="n">get_args</span><span class="p">(</span><span class="n">annotation_type</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">annotation_args</span><span class="p">:</span>
|
|
<span class="n">annotation_type</span> <span class="o">=</span> <span class="n">annotation_args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">break</span>
|
|
<span class="k">elif</span> <span class="n">annotation_origin</span> <span class="ow">is</span> <span class="n">Required</span><span class="p">:</span>
|
|
<span class="k">yield</span> <span class="n">Required</span>
|
|
<span class="p">(</span><span class="n">annotation_type</span><span class="p">,)</span> <span class="o">=</span> <span class="n">get_args</span><span class="p">(</span><span class="n">annotation_type</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">annotation_origin</span> <span class="ow">is</span> <span class="n">NotRequired</span><span class="p">:</span>
|
|
<span class="k">yield</span> <span class="n">NotRequired</span>
|
|
<span class="p">(</span><span class="n">annotation_type</span><span class="p">,)</span> <span class="o">=</span> <span class="n">get_args</span><span class="p">(</span><span class="n">annotation_type</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">annotation_origin</span> <span class="ow">is</span> <span class="n">ReadOnly</span><span class="p">:</span>
|
|
<span class="k">yield</span> <span class="n">ReadOnly</span>
|
|
<span class="p">(</span><span class="n">annotation_type</span><span class="p">,)</span> <span class="o">=</span> <span class="n">get_args</span><span class="p">(</span><span class="n">annotation_type</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">break</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_TypedDictMeta</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">ns</span><span class="p">,</span> <span class="n">total</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Create a new typed dict class object.</span>
|
|
|
|
<span class="sd"> This method is called when TypedDict is subclassed,</span>
|
|
<span class="sd"> or when TypedDict is instantiated. This way</span>
|
|
<span class="sd"> TypedDict supports all three syntax forms described in its docstring.</span>
|
|
<span class="sd"> Subclasses and instances of TypedDict return actual dictionaries.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">base</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_TypedDictMeta</span> <span class="ow">and</span> <span class="n">base</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">Generic</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'cannot inherit from both a TypedDict type '</span>
|
|
<span class="s1">'and a non-TypedDict base class'</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="nb">issubclass</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">Generic</span><span class="p">)</span> <span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">):</span>
|
|
<span class="n">generic_base</span> <span class="o">=</span> <span class="p">(</span><span class="n">Generic</span><span class="p">,)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">generic_base</span> <span class="o">=</span> <span class="p">()</span>
|
|
|
|
<span class="n">tp_dict</span> <span class="o">=</span> <span class="nb">type</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="n">_TypedDictMeta</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="p">(</span><span class="o">*</span><span class="n">generic_base</span><span class="p">,</span> <span class="nb">dict</span><span class="p">),</span> <span class="n">ns</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">tp_dict</span><span class="p">,</span> <span class="s1">'__orig_bases__'</span><span class="p">):</span>
|
|
<span class="n">tp_dict</span><span class="o">.</span><span class="n">__orig_bases__</span> <span class="o">=</span> <span class="n">bases</span>
|
|
|
|
<span class="n">annotations</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">own_annotations</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__annotations__'</span><span class="p">,</span> <span class="p">{})</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s2">"TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"</span>
|
|
<span class="n">own_annotations</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="n">n</span><span class="p">:</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="n">tp_dict</span><span class="o">.</span><span class="vm">__module__</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">n</span><span class="p">,</span> <span class="n">tp</span> <span class="ow">in</span> <span class="n">own_annotations</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
|
<span class="p">}</span>
|
|
<span class="n">required_keys</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="n">optional_keys</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="n">readonly_keys</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="n">mutable_keys</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="n">annotations</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__annotations__'</span><span class="p">,</span> <span class="p">{}))</span>
|
|
|
|
<span class="n">base_required</span> <span class="o">=</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__required_keys__'</span><span class="p">,</span> <span class="nb">set</span><span class="p">())</span>
|
|
<span class="n">required_keys</span> <span class="o">|=</span> <span class="n">base_required</span>
|
|
<span class="n">optional_keys</span> <span class="o">-=</span> <span class="n">base_required</span>
|
|
|
|
<span class="n">base_optional</span> <span class="o">=</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__optional_keys__'</span><span class="p">,</span> <span class="nb">set</span><span class="p">())</span>
|
|
<span class="n">required_keys</span> <span class="o">-=</span> <span class="n">base_optional</span>
|
|
<span class="n">optional_keys</span> <span class="o">|=</span> <span class="n">base_optional</span>
|
|
|
|
<span class="n">readonly_keys</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__readonly_keys__'</span><span class="p">,</span> <span class="p">()))</span>
|
|
<span class="n">mutable_keys</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__mutable_keys__'</span><span class="p">,</span> <span class="p">()))</span>
|
|
|
|
<span class="n">annotations</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">own_annotations</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">annotation_key</span><span class="p">,</span> <span class="n">annotation_type</span> <span class="ow">in</span> <span class="n">own_annotations</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="n">qualifiers</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">_get_typeddict_qualifiers</span><span class="p">(</span><span class="n">annotation_type</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">Required</span> <span class="ow">in</span> <span class="n">qualifiers</span><span class="p">:</span>
|
|
<span class="n">is_required</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">elif</span> <span class="n">NotRequired</span> <span class="ow">in</span> <span class="n">qualifiers</span><span class="p">:</span>
|
|
<span class="n">is_required</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">is_required</span> <span class="o">=</span> <span class="n">total</span>
|
|
|
|
<span class="k">if</span> <span class="n">is_required</span><span class="p">:</span>
|
|
<span class="n">required_keys</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">annotation_key</span><span class="p">)</span>
|
|
<span class="n">optional_keys</span><span class="o">.</span><span class="n">discard</span><span class="p">(</span><span class="n">annotation_key</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">optional_keys</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">annotation_key</span><span class="p">)</span>
|
|
<span class="n">required_keys</span><span class="o">.</span><span class="n">discard</span><span class="p">(</span><span class="n">annotation_key</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">ReadOnly</span> <span class="ow">in</span> <span class="n">qualifiers</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">annotation_key</span> <span class="ow">in</span> <span class="n">mutable_keys</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Cannot override mutable key </span><span class="si">{</span><span class="n">annotation_key</span><span class="si">!r}</span><span class="s2">"</span>
|
|
<span class="s2">" with read-only key"</span>
|
|
<span class="p">)</span>
|
|
<span class="n">readonly_keys</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">annotation_key</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">mutable_keys</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">annotation_key</span><span class="p">)</span>
|
|
<span class="n">readonly_keys</span><span class="o">.</span><span class="n">discard</span><span class="p">(</span><span class="n">annotation_key</span><span class="p">)</span>
|
|
|
|
<span class="k">assert</span> <span class="n">required_keys</span><span class="o">.</span><span class="n">isdisjoint</span><span class="p">(</span><span class="n">optional_keys</span><span class="p">),</span> <span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Required keys overlap with optional keys in </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2">:"</span>
|
|
<span class="sa">f</span><span class="s2">" </span><span class="si">{</span><span class="n">required_keys</span><span class="si">=}</span><span class="s2">, </span><span class="si">{</span><span class="n">optional_keys</span><span class="si">=}</span><span class="s2">"</span>
|
|
<span class="p">)</span>
|
|
<span class="n">tp_dict</span><span class="o">.</span><span class="vm">__annotations__</span> <span class="o">=</span> <span class="n">annotations</span>
|
|
<span class="n">tp_dict</span><span class="o">.</span><span class="n">__required_keys__</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">(</span><span class="n">required_keys</span><span class="p">)</span>
|
|
<span class="n">tp_dict</span><span class="o">.</span><span class="n">__optional_keys__</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">(</span><span class="n">optional_keys</span><span class="p">)</span>
|
|
<span class="n">tp_dict</span><span class="o">.</span><span class="n">__readonly_keys__</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">(</span><span class="n">readonly_keys</span><span class="p">)</span>
|
|
<span class="n">tp_dict</span><span class="o">.</span><span class="n">__mutable_keys__</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">(</span><span class="n">mutable_keys</span><span class="p">)</span>
|
|
<span class="n">tp_dict</span><span class="o">.</span><span class="n">__total__</span> <span class="o">=</span> <span class="n">total</span>
|
|
<span class="k">return</span> <span class="n">tp_dict</span>
|
|
|
|
<span class="fm">__call__</span> <span class="o">=</span> <span class="nb">dict</span> <span class="c1"># static method</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__subclasscheck__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="c1"># Typed dicts are only for static structural subtyping.</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'TypedDict does not support instance and class checks'</span><span class="p">)</span>
|
|
|
|
<span class="fm">__instancecheck__</span> <span class="o">=</span> <span class="fm">__subclasscheck__</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">TypedDict</span><span class="p">(</span><span class="n">typename</span><span class="p">,</span> <span class="n">fields</span><span class="o">=</span><span class="n">_sentinel</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">total</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""A simple typed namespace. At runtime it is equivalent to a plain dict.</span>
|
|
|
|
<span class="sd"> TypedDict creates a dictionary type such that a type checker will expect all</span>
|
|
<span class="sd"> instances to have a certain set of keys, where each key is</span>
|
|
<span class="sd"> associated with a value of a consistent type. This expectation</span>
|
|
<span class="sd"> is not checked at runtime.</span>
|
|
|
|
<span class="sd"> Usage::</span>
|
|
|
|
<span class="sd"> >>> class Point2D(TypedDict):</span>
|
|
<span class="sd"> ... x: int</span>
|
|
<span class="sd"> ... y: int</span>
|
|
<span class="sd"> ... label: str</span>
|
|
<span class="sd"> ...</span>
|
|
<span class="sd"> >>> a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK</span>
|
|
<span class="sd"> >>> b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check</span>
|
|
<span class="sd"> >>> Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')</span>
|
|
<span class="sd"> True</span>
|
|
|
|
<span class="sd"> The type info can be accessed via the Point2D.__annotations__ dict, and</span>
|
|
<span class="sd"> the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets.</span>
|
|
<span class="sd"> TypedDict supports an additional equivalent form::</span>
|
|
|
|
<span class="sd"> Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})</span>
|
|
|
|
<span class="sd"> By default, all keys must be present in a TypedDict. It is possible</span>
|
|
<span class="sd"> to override this by specifying totality::</span>
|
|
|
|
<span class="sd"> class Point2D(TypedDict, total=False):</span>
|
|
<span class="sd"> x: int</span>
|
|
<span class="sd"> y: int</span>
|
|
|
|
<span class="sd"> This means that a Point2D TypedDict can have any of the keys omitted. A type</span>
|
|
<span class="sd"> checker is only expected to support a literal False or True as the value of</span>
|
|
<span class="sd"> the total argument. True is the default, and makes all items defined in the</span>
|
|
<span class="sd"> class body be required.</span>
|
|
|
|
<span class="sd"> The Required and NotRequired special forms can also be used to mark</span>
|
|
<span class="sd"> individual keys as being required or not required::</span>
|
|
|
|
<span class="sd"> class Point2D(TypedDict):</span>
|
|
<span class="sd"> x: int # the "x" key must always be present (Required is the default)</span>
|
|
<span class="sd"> y: NotRequired[int] # the "y" key can be omitted</span>
|
|
|
|
<span class="sd"> See PEP 655 for more details on Required and NotRequired.</span>
|
|
|
|
<span class="sd"> The ReadOnly special form can be used</span>
|
|
<span class="sd"> to mark individual keys as immutable for type checkers::</span>
|
|
|
|
<span class="sd"> class DatabaseUser(TypedDict):</span>
|
|
<span class="sd"> id: ReadOnly[int] # the "id" key must not be modified</span>
|
|
<span class="sd"> username: str # the "username" key can be changed</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">fields</span> <span class="ow">is</span> <span class="n">_sentinel</span> <span class="ow">or</span> <span class="n">fields</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">warnings</span>
|
|
|
|
<span class="k">if</span> <span class="n">fields</span> <span class="ow">is</span> <span class="n">_sentinel</span><span class="p">:</span>
|
|
<span class="n">deprecated_thing</span> <span class="o">=</span> <span class="s2">"Failing to pass a value for the 'fields' parameter"</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">deprecated_thing</span> <span class="o">=</span> <span class="s2">"Passing `None` as the 'fields' parameter"</span>
|
|
|
|
<span class="n">example</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"`</span><span class="si">{</span><span class="n">typename</span><span class="si">}</span><span class="s2"> = TypedDict(</span><span class="si">{</span><span class="n">typename</span><span class="si">!r}</span><span class="s2">, </span><span class="se">{{{{}}}}</span><span class="s2">)`"</span>
|
|
<span class="n">deprecation_msg</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="s2">"</span><span class="si">{name}</span><span class="s2"> is deprecated and will be disallowed in Python </span><span class="si">{remove}</span><span class="s2">. "</span>
|
|
<span class="s2">"To create a TypedDict class with 0 fields "</span>
|
|
<span class="s2">"using the functional syntax, "</span>
|
|
<span class="s2">"pass an empty dictionary, e.g. "</span>
|
|
<span class="p">)</span> <span class="o">+</span> <span class="n">example</span> <span class="o">+</span> <span class="s2">"."</span>
|
|
<span class="n">warnings</span><span class="o">.</span><span class="n">_deprecated</span><span class="p">(</span><span class="n">deprecated_thing</span><span class="p">,</span> <span class="n">message</span><span class="o">=</span><span class="n">deprecation_msg</span><span class="p">,</span> <span class="n">remove</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">15</span><span class="p">))</span>
|
|
<span class="n">fields</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="n">ns</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'__annotations__'</span><span class="p">:</span> <span class="nb">dict</span><span class="p">(</span><span class="n">fields</span><span class="p">)}</span>
|
|
<span class="n">module</span> <span class="o">=</span> <span class="n">_caller</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="n">module</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># Setting correct module is necessary to make typed dict classes pickleable.</span>
|
|
<span class="n">ns</span><span class="p">[</span><span class="s1">'__module__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">module</span>
|
|
|
|
<span class="n">td</span> <span class="o">=</span> <span class="n">_TypedDictMeta</span><span class="p">(</span><span class="n">typename</span><span class="p">,</span> <span class="p">(),</span> <span class="n">ns</span><span class="p">,</span> <span class="n">total</span><span class="o">=</span><span class="n">total</span><span class="p">)</span>
|
|
<span class="n">td</span><span class="o">.</span><span class="n">__orig_bases__</span> <span class="o">=</span> <span class="p">(</span><span class="n">TypedDict</span><span class="p">,)</span>
|
|
<span class="k">return</span> <span class="n">td</span>
|
|
|
|
<span class="n">_TypedDict</span> <span class="o">=</span> <span class="nb">type</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="n">_TypedDictMeta</span><span class="p">,</span> <span class="s1">'TypedDict'</span><span class="p">,</span> <span class="p">(),</span> <span class="p">{})</span>
|
|
<span class="n">TypedDict</span><span class="o">.</span><span class="n">__mro_entries__</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">bases</span><span class="p">:</span> <span class="p">(</span><span class="n">_TypedDict</span><span class="p">,)</span>
|
|
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">Required</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Special typing construct to mark a TypedDict key as required.</span>
|
|
|
|
<span class="sd"> This is mainly useful for total=False TypedDicts.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> class Movie(TypedDict, total=False):</span>
|
|
<span class="sd"> title: Required[str]</span>
|
|
<span class="sd"> year: int</span>
|
|
|
|
<span class="sd"> m = Movie(</span>
|
|
<span class="sd"> title='The Matrix', # typechecker error if key is omitted</span>
|
|
<span class="sd"> year=1999,</span>
|
|
<span class="sd"> )</span>
|
|
|
|
<span class="sd"> There is no runtime checking that a required key is actually provided</span>
|
|
<span class="sd"> when instantiating a related TypedDict.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">item</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="si">}</span><span class="s1"> accepts only a single type.'</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_GenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="p">(</span><span class="n">item</span><span class="p">,))</span>
|
|
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">NotRequired</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Special typing construct to mark a TypedDict key as potentially missing.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> class Movie(TypedDict):</span>
|
|
<span class="sd"> title: str</span>
|
|
<span class="sd"> year: NotRequired[int]</span>
|
|
|
|
<span class="sd"> m = Movie(</span>
|
|
<span class="sd"> title='The Matrix', # typechecker error if key is omitted</span>
|
|
<span class="sd"> year=1999,</span>
|
|
<span class="sd"> )</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">item</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="si">}</span><span class="s1"> accepts only a single type.'</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_GenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="p">(</span><span class="n">item</span><span class="p">,))</span>
|
|
|
|
|
|
<span class="nd">@_SpecialForm</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">ReadOnly</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""A special typing construct to mark an item of a TypedDict as read-only.</span>
|
|
|
|
<span class="sd"> For example::</span>
|
|
|
|
<span class="sd"> class Movie(TypedDict):</span>
|
|
<span class="sd"> title: ReadOnly[str]</span>
|
|
<span class="sd"> year: int</span>
|
|
|
|
<span class="sd"> def mutate_movie(m: Movie) -> None:</span>
|
|
<span class="sd"> m["year"] = 1992 # allowed</span>
|
|
<span class="sd"> m["title"] = "The Matrix" # typechecker error</span>
|
|
|
|
<span class="sd"> There is no runtime checking for this property.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">item</span> <span class="o">=</span> <span class="n">_type_check</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="si">}</span><span class="s1"> accepts only a single type.'</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_GenericAlias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="p">(</span><span class="n">item</span><span class="p">,))</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">NewType</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""NewType creates simple unique types with almost zero runtime overhead.</span>
|
|
|
|
<span class="sd"> NewType(name, tp) is considered a subtype of tp</span>
|
|
<span class="sd"> by static type checkers. At runtime, NewType(name, tp) returns</span>
|
|
<span class="sd"> a dummy callable that simply returns its argument.</span>
|
|
|
|
<span class="sd"> Usage::</span>
|
|
|
|
<span class="sd"> UserId = NewType('UserId', int)</span>
|
|
|
|
<span class="sd"> def name_by_id(user_id: UserId) -> str:</span>
|
|
<span class="sd"> ...</span>
|
|
|
|
<span class="sd"> UserId('user') # Fails type check</span>
|
|
|
|
<span class="sd"> name_by_id(42) # Fails type check</span>
|
|
<span class="sd"> name_by_id(UserId(42)) # OK</span>
|
|
|
|
<span class="sd"> num = UserId(5) + 1 # type: int</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="fm">__call__</span> <span class="o">=</span> <span class="n">_idfunc</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">tp</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="vm">__qualname__</span> <span class="o">=</span> <span class="n">name</span>
|
|
<span class="k">if</span> <span class="s1">'.'</span> <span class="ow">in</span> <span class="n">name</span><span class="p">:</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="n">rpartition</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="vm">__name__</span> <span class="o">=</span> <span class="n">name</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">__supertype__</span> <span class="o">=</span> <span class="n">tp</span>
|
|
<span class="n">def_mod</span> <span class="o">=</span> <span class="n">_caller</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="n">def_mod</span> <span class="o">!=</span> <span class="s1">'typing'</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span> <span class="o">=</span> <span class="n">def_mod</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__mro_entries__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span>
|
|
<span class="c1"># We defined __mro_entries__ to get a better error message</span>
|
|
<span class="c1"># if a user attempts to subclass a NewType instance. bpo-46170</span>
|
|
<span class="n">superclass_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__name__</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">Dummy</span><span class="p">:</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__init_subclass__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="n">subclass_name</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Cannot subclass an instance of NewType. Perhaps you were looking for: "</span>
|
|
<span class="sa">f</span><span class="s2">"`</span><span class="si">{</span><span class="n">subclass_name</span><span class="si">}</span><span class="s2"> = NewType(</span><span class="si">{</span><span class="n">subclass_name</span><span class="si">!r}</span><span class="s2">, </span><span class="si">{</span><span class="n">superclass_name</span><span class="si">}</span><span class="s2">)`"</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="p">(</span><span class="n">Dummy</span><span class="p">,)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s1">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__qualname__</span><span class="si">}</span><span class="s1">'</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__qualname__</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__or__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__ror__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="p">]</span>
|
|
|
|
|
|
<span class="c1"># Python-version-specific alias (Python 2: unicode; Python 3: str)</span>
|
|
<span class="n">Text</span> <span class="o">=</span> <span class="nb">str</span>
|
|
|
|
|
|
<span class="c1"># Constant that's True when type checking, but False here.</span>
|
|
<span class="n">TYPE_CHECKING</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">IO</span><span class="p">(</span><span class="n">Generic</span><span class="p">[</span><span class="n">AnyStr</span><span class="p">]):</span>
|
|
<span class="w"> </span><span class="sd">"""Generic base class for TextIO and BinaryIO.</span>
|
|
|
|
<span class="sd"> This is an abstract, generic version of the return of open().</span>
|
|
|
|
<span class="sd"> NOTE: This does not distinguish between the different possible</span>
|
|
<span class="sd"> classes (text vs. binary, read vs. write vs. read/write,</span>
|
|
<span class="sd"> append-only, unbuffered). The TextIO and BinaryIO subclasses</span>
|
|
<span class="sd"> below capture the distinctions between text vs. binary, which is</span>
|
|
<span class="sd"> pervasive in the interface; however we currently do not offer a</span>
|
|
<span class="sd"> way to track the other distinctions in the type system.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">mode</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">closed</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">fileno</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">flush</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isatty</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">n</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">-></span> <span class="n">AnyStr</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">readable</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">readline</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">limit</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">-></span> <span class="n">AnyStr</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">readlines</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">hint</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">AnyStr</span><span class="p">]:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">seek</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">offset</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">whence</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">seekable</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">tell</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">truncate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">writable</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">s</span><span class="p">:</span> <span class="n">AnyStr</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">writelines</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lines</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">AnyStr</span><span class="p">])</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'IO[AnyStr]'</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">traceback</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">BinaryIO</span><span class="p">(</span><span class="n">IO</span><span class="p">[</span><span class="nb">bytes</span><span class="p">]):</span>
|
|
<span class="w"> </span><span class="sd">"""Typed version of the return of open() in binary mode."""</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">s</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">bytes</span><span class="p">,</span> <span class="nb">bytearray</span><span class="p">])</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'BinaryIO'</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">TextIO</span><span class="p">(</span><span class="n">IO</span><span class="p">[</span><span class="nb">str</span><span class="p">]):</span>
|
|
<span class="w"> </span><span class="sd">"""Typed version of the return of open() in text mode."""</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">buffer</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">BinaryIO</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">encoding</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">errors</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">line_buffering</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">newlines</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Any</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="nd">@abstractmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'TextIO'</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">reveal_type</span><span class="p">[</span><span class="n">T</span><span class="p">](</span><span class="n">obj</span><span class="p">:</span> <span class="n">T</span><span class="p">,</span> <span class="o">/</span><span class="p">)</span> <span class="o">-></span> <span class="n">T</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Ask a static type checker to reveal the inferred type of an expression.</span>
|
|
|
|
<span class="sd"> When a static type checker encounters a call to ``reveal_type()``,</span>
|
|
<span class="sd"> it will emit the inferred type of the argument::</span>
|
|
|
|
<span class="sd"> x: int = 1</span>
|
|
<span class="sd"> reveal_type(x)</span>
|
|
|
|
<span class="sd"> Running a static type checker (e.g., mypy) on this example</span>
|
|
<span class="sd"> will produce output similar to 'Revealed type is "builtins.int"'.</span>
|
|
|
|
<span class="sd"> At runtime, the function prints the runtime type of the</span>
|
|
<span class="sd"> argument and returns the argument unchanged.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Runtime type is </span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="si">!r}</span><span class="s2">"</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">obj</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_IdentityCallable</span><span class="p">(</span><span class="n">Protocol</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">[</span><span class="n">T</span><span class="p">](</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">:</span> <span class="n">T</span><span class="p">,</span> <span class="o">/</span><span class="p">)</span> <span class="o">-></span> <span class="n">T</span><span class="p">:</span>
|
|
<span class="o">...</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">dataclass_transform</span><span class="p">(</span>
|
|
<span class="o">*</span><span class="p">,</span>
|
|
<span class="n">eq_default</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
|
|
<span class="n">order_default</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
|
<span class="n">kw_only_default</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
|
<span class="n">frozen_default</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
|
<span class="n">field_specifiers</span><span class="p">:</span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">type</span><span class="p">[</span><span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span> <span class="o">...</span><span class="p">]</span> <span class="o">=</span> <span class="p">(),</span>
|
|
<span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">Any</span><span class="p">,</span>
|
|
<span class="p">)</span> <span class="o">-></span> <span class="n">_IdentityCallable</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Decorator to mark an object as providing dataclass-like behaviour.</span>
|
|
|
|
<span class="sd"> The decorator can be applied to a function, class, or metaclass.</span>
|
|
|
|
<span class="sd"> Example usage with a decorator function::</span>
|
|
|
|
<span class="sd"> @dataclass_transform()</span>
|
|
<span class="sd"> def create_model[T](cls: type[T]) -> type[T]:</span>
|
|
<span class="sd"> ...</span>
|
|
<span class="sd"> return cls</span>
|
|
|
|
<span class="sd"> @create_model</span>
|
|
<span class="sd"> class CustomerModel:</span>
|
|
<span class="sd"> id: int</span>
|
|
<span class="sd"> name: str</span>
|
|
|
|
<span class="sd"> On a base class::</span>
|
|
|
|
<span class="sd"> @dataclass_transform()</span>
|
|
<span class="sd"> class ModelBase: ...</span>
|
|
|
|
<span class="sd"> class CustomerModel(ModelBase):</span>
|
|
<span class="sd"> id: int</span>
|
|
<span class="sd"> name: str</span>
|
|
|
|
<span class="sd"> On a metaclass::</span>
|
|
|
|
<span class="sd"> @dataclass_transform()</span>
|
|
<span class="sd"> class ModelMeta(type): ...</span>
|
|
|
|
<span class="sd"> class ModelBase(metaclass=ModelMeta): ...</span>
|
|
|
|
<span class="sd"> class CustomerModel(ModelBase):</span>
|
|
<span class="sd"> id: int</span>
|
|
<span class="sd"> name: str</span>
|
|
|
|
<span class="sd"> The ``CustomerModel`` classes defined above will</span>
|
|
<span class="sd"> be treated by type checkers similarly to classes created with</span>
|
|
<span class="sd"> ``@dataclasses.dataclass``.</span>
|
|
<span class="sd"> For example, type checkers will assume these classes have</span>
|
|
<span class="sd"> ``__init__`` methods that accept ``id`` and ``name``.</span>
|
|
|
|
<span class="sd"> The arguments to this decorator can be used to customize this behavior:</span>
|
|
<span class="sd"> - ``eq_default`` indicates whether the ``eq`` parameter is assumed to be</span>
|
|
<span class="sd"> ``True`` or ``False`` if it is omitted by the caller.</span>
|
|
<span class="sd"> - ``order_default`` indicates whether the ``order`` parameter is</span>
|
|
<span class="sd"> assumed to be True or False if it is omitted by the caller.</span>
|
|
<span class="sd"> - ``kw_only_default`` indicates whether the ``kw_only`` parameter is</span>
|
|
<span class="sd"> assumed to be True or False if it is omitted by the caller.</span>
|
|
<span class="sd"> - ``frozen_default`` indicates whether the ``frozen`` parameter is</span>
|
|
<span class="sd"> assumed to be True or False if it is omitted by the caller.</span>
|
|
<span class="sd"> - ``field_specifiers`` specifies a static list of supported classes</span>
|
|
<span class="sd"> or functions that describe fields, similar to ``dataclasses.field()``.</span>
|
|
<span class="sd"> - Arbitrary other keyword arguments are accepted in order to allow for</span>
|
|
<span class="sd"> possible future extensions.</span>
|
|
|
|
<span class="sd"> At runtime, this decorator records its arguments in the</span>
|
|
<span class="sd"> ``__dataclass_transform__`` attribute on the decorated object.</span>
|
|
<span class="sd"> It has no other runtime effect.</span>
|
|
|
|
<span class="sd"> See PEP 681 for more details.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">decorator</span><span class="p">(</span><span class="n">cls_or_fn</span><span class="p">):</span>
|
|
<span class="n">cls_or_fn</span><span class="o">.</span><span class="n">__dataclass_transform__</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s2">"eq_default"</span><span class="p">:</span> <span class="n">eq_default</span><span class="p">,</span>
|
|
<span class="s2">"order_default"</span><span class="p">:</span> <span class="n">order_default</span><span class="p">,</span>
|
|
<span class="s2">"kw_only_default"</span><span class="p">:</span> <span class="n">kw_only_default</span><span class="p">,</span>
|
|
<span class="s2">"frozen_default"</span><span class="p">:</span> <span class="n">frozen_default</span><span class="p">,</span>
|
|
<span class="s2">"field_specifiers"</span><span class="p">:</span> <span class="n">field_specifiers</span><span class="p">,</span>
|
|
<span class="s2">"kwargs"</span><span class="p">:</span> <span class="n">kwargs</span><span class="p">,</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="n">cls_or_fn</span>
|
|
<span class="k">return</span> <span class="n">decorator</span>
|
|
|
|
|
|
<span class="nb">type</span> <span class="n">_Func</span> <span class="o">=</span> <span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">override</span><span class="p">[</span><span class="n">F</span><span class="p">:</span> <span class="n">_Func</span><span class="p">](</span><span class="n">method</span><span class="p">:</span> <span class="n">F</span><span class="p">,</span> <span class="o">/</span><span class="p">)</span> <span class="o">-></span> <span class="n">F</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Indicate that a method is intended to override a method in a base class.</span>
|
|
|
|
<span class="sd"> Usage::</span>
|
|
|
|
<span class="sd"> class Base:</span>
|
|
<span class="sd"> def method(self) -> None:</span>
|
|
<span class="sd"> pass</span>
|
|
|
|
<span class="sd"> class Child(Base):</span>
|
|
<span class="sd"> @override</span>
|
|
<span class="sd"> def method(self) -> None:</span>
|
|
<span class="sd"> super().method()</span>
|
|
|
|
<span class="sd"> When this decorator is applied to a method, the type checker will</span>
|
|
<span class="sd"> validate that it overrides a method or attribute with the same name on a</span>
|
|
<span class="sd"> base class. This helps prevent bugs that may occur when a base class is</span>
|
|
<span class="sd"> changed without an equivalent change to a child class.</span>
|
|
|
|
<span class="sd"> There is no runtime checking of this property. The decorator attempts to</span>
|
|
<span class="sd"> set the ``__override__`` attribute to ``True`` on the decorated object to</span>
|
|
<span class="sd"> allow runtime introspection.</span>
|
|
|
|
<span class="sd"> See PEP 698 for details.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">method</span><span class="o">.</span><span class="n">__override__</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">AttributeError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
|
|
<span class="c1"># Skip the attribute silently if it is not writable.</span>
|
|
<span class="c1"># AttributeError happens if the object has __slots__ or a</span>
|
|
<span class="c1"># read-only property, TypeError if it's a builtin class.</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">return</span> <span class="n">method</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">is_protocol</span><span class="p">(</span><span class="n">tp</span><span class="p">:</span> <span class="nb">type</span><span class="p">,</span> <span class="o">/</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Return True if the given type is a Protocol.</span>
|
|
|
|
<span class="sd"> Example::</span>
|
|
|
|
<span class="sd"> >>> from typing import Protocol, is_protocol</span>
|
|
<span class="sd"> >>> class P(Protocol):</span>
|
|
<span class="sd"> ... def a(self) -> str: ...</span>
|
|
<span class="sd"> ... b: int</span>
|
|
<span class="sd"> >>> is_protocol(P)</span>
|
|
<span class="sd"> True</span>
|
|
<span class="sd"> >>> is_protocol(int)</span>
|
|
<span class="sd"> False</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="nb">isinstance</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="nb">type</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="s1">'_is_protocol'</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="n">tp</span> <span class="o">!=</span> <span class="n">Protocol</span>
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_protocol_members</span><span class="p">(</span><span class="n">tp</span><span class="p">:</span> <span class="nb">type</span><span class="p">,</span> <span class="o">/</span><span class="p">)</span> <span class="o">-></span> <span class="nb">frozenset</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
|
|
<span class="w"> </span><span class="sd">"""Return the set of members defined in a Protocol.</span>
|
|
|
|
<span class="sd"> Example::</span>
|
|
|
|
<span class="sd"> >>> from typing import Protocol, get_protocol_members</span>
|
|
<span class="sd"> >>> class P(Protocol):</span>
|
|
<span class="sd"> ... def a(self) -> str: ...</span>
|
|
<span class="sd"> ... b: int</span>
|
|
<span class="sd"> >>> get_protocol_members(P) == frozenset({'a', 'b'})</span>
|
|
<span class="sd"> True</span>
|
|
|
|
<span class="sd"> Raise a TypeError for arguments that are not Protocols.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">is_protocol</span><span class="p">(</span><span class="n">tp</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">tp</span><span class="si">!r}</span><span class="s1"> is not a Protocol'</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">frozenset</span><span class="p">(</span><span class="n">tp</span><span class="o">.</span><span class="n">__protocol_attrs__</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__getattr__</span><span class="p">(</span><span class="n">attr</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Improve the import time of the typing module.</span>
|
|
|
|
<span class="sd"> Soft-deprecated objects which are costly to create</span>
|
|
<span class="sd"> are only created on-demand here.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">{</span><span class="s2">"Pattern"</span><span class="p">,</span> <span class="s2">"Match"</span><span class="p">}:</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">re</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="n">re</span><span class="p">,</span> <span class="n">attr</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">attr</span> <span class="ow">in</span> <span class="p">{</span><span class="s2">"ContextManager"</span><span class="p">,</span> <span class="s2">"AsyncContextManager"</span><span class="p">}:</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">contextlib</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="n">_alias</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="n">contextlib</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"Abstract</span><span class="si">{</span><span class="n">attr</span><span class="si">}</span><span class="s2">"</span><span class="p">),</span> <span class="mi">2</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">attr</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="p">(</span><span class="nb">bool</span> <span class="o">|</span> <span class="kc">None</span><span class="p">,))</span>
|
|
<span class="k">elif</span> <span class="n">attr</span> <span class="o">==</span> <span class="s2">"_collect_parameters"</span><span class="p">:</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">warnings</span>
|
|
|
|
<span class="n">depr_message</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="s2">"The private _collect_parameters function is deprecated and will be"</span>
|
|
<span class="s2">" removed in a future version of Python. Any use of private functions"</span>
|
|
<span class="s2">" is discouraged and may break in the future."</span>
|
|
<span class="p">)</span>
|
|
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">depr_message</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="ne">DeprecationWarning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="n">_collect_type_parameters</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"module </span><span class="si">{</span><span class="vm">__name__</span><span class="si">!r}</span><span class="s2"> has no attribute </span><span class="si">{</span><span class="n">attr</span><span class="si">!r}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="nb">globals</span><span class="p">()[</span><span class="n">attr</span><span class="p">]</span> <span class="o">=</span> <span class="n">obj</span>
|
|
<span class="k">return</span> <span class="n">obj</span>
|
|
</pre></div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<div class="related" role="navigation" aria-label="related navigation">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../genindex.html" title="General Index"
|
|
>index</a></li>
|
|
<li class="right" >
|
|
<a href="../py-modindex.html" title="Python Module Index"
|
|
>modules</a> |</li>
|
|
<li class="nav-item nav-item-0"><a href="../index.html">Evennia latest</a> »</li>
|
|
<li class="nav-item nav-item-1"><a href="index.html" >Module code</a> »</li>
|
|
<li class="nav-item nav-item-this"><a href="">typing</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="footer" role="contentinfo">
|
|
© Copyright 2024, The Evennia developer community.
|
|
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
|
|
</div>
|
|
</body>
|
|
</html> |