blob: f50252fd29e2bf688931420efc03c2702c48e22e [file] [log] [blame]
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>apache_beam.typehints.typehints &mdash; Apache Beam 2.47.0 documentation</title>
<script type="text/javascript" src="../../../_static/js/modernizr.min.js"></script>
<script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/language_data.js"></script>
<script async="async" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/javascript" src="../../../_static/js/theme.js"></script>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../../../index.html" class="icon icon-home"> Apache Beam
</a>
<div class="version">
2.47.0
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.coders.html">apache_beam.coders package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.dataframe.html">apache_beam.dataframe package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.io.html">apache_beam.io package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.metrics.html">apache_beam.metrics package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.ml.html">apache_beam.ml package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.options.html">apache_beam.options package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.portability.html">apache_beam.portability package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.runners.html">apache_beam.runners package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.testing.html">apache_beam.testing package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.transforms.html">apache_beam.transforms package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.typehints.html">apache_beam.typehints package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.utils.html">apache_beam.utils package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.yaml.html">apache_beam.yaml package</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.error.html">apache_beam.error module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.pipeline.html">apache_beam.pipeline module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.pvalue.html">apache_beam.pvalue module</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../../index.html">Apache Beam</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../../index.html">Docs</a> &raquo;</li>
<li><a href="../../index.html">Module code</a> &raquo;</li>
<li>apache_beam.typehints.typehints</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for apache_beam.typehints.typehints</h1><div class="highlight"><pre>
<span></span><span class="c1">#</span>
<span class="c1"># Licensed to the Apache Software Foundation (ASF) under one or more</span>
<span class="c1"># contributor license agreements. See the NOTICE file distributed with</span>
<span class="c1"># this work for additional information regarding copyright ownership.</span>
<span class="c1"># The ASF licenses this file to You under the Apache License, Version 2.0</span>
<span class="c1"># (the &quot;License&quot;); you may not use this file except in compliance with</span>
<span class="c1"># the License. You may obtain a copy of the License at</span>
<span class="c1">#</span>
<span class="c1"># http://www.apache.org/licenses/LICENSE-2.0</span>
<span class="c1">#</span>
<span class="c1"># Unless required by applicable law or agreed to in writing, software</span>
<span class="c1"># distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span>
<span class="c1"># WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
<span class="c1"># See the License for the specific language governing permissions and</span>
<span class="c1"># limitations under the License.</span>
<span class="c1">#</span>
<span class="sd">&quot;&quot;&quot;Syntax &amp; semantics for type-hinting custom-functions/PTransforms in the SDK.</span>
<span class="sd">This module defines type-hinting objects and the corresponding syntax for</span>
<span class="sd">type-hinting function arguments, function return types, or PTransform object</span>
<span class="sd">themselves. TypeHint&#39;s defined in the module can be used to implement either</span>
<span class="sd">static or run-time type-checking in regular Python code.</span>
<span class="sd">Type-hints are defined by &#39;indexing&#39; a type-parameter into a defined</span>
<span class="sd">CompositeTypeHint instance:</span>
<span class="sd"> * &#39;List[int]&#39;.</span>
<span class="sd">Valid type-hints are partitioned into two categories: simple, and composite.</span>
<span class="sd">Simple type hints are type hints based on a subset of Python primitive types:</span>
<span class="sd">int, bool, float, str, object, None, and bytes. No other primitive types are</span>
<span class="sd">allowed.</span>
<span class="sd">Composite type-hints are reserved for hinting the types of container-like</span>
<span class="sd">Python objects such as &#39;list&#39;. Composite type-hints can be parameterized by an</span>
<span class="sd">inner simple or composite type-hint, using the &#39;indexing&#39; syntax. In order to</span>
<span class="sd">avoid conflicting with the namespace of the built-in container types, when</span>
<span class="sd">specifying this category of type-hints, the first letter should be capitalized.</span>
<span class="sd">The following composite type-hints are permitted. NOTE: &#39;T&#39; can be any of the</span>
<span class="sd">type-hints listed or a simple Python type:</span>
<span class="sd"> * Any</span>
<span class="sd"> * Union[T, T, T]</span>
<span class="sd"> * Optional[T]</span>
<span class="sd"> * Tuple[T, T]</span>
<span class="sd"> * Tuple[T, ...]</span>
<span class="sd"> * List[T]</span>
<span class="sd"> * KV[T, T]</span>
<span class="sd"> * Dict[T, T]</span>
<span class="sd"> * Set[T]</span>
<span class="sd"> * Iterable[T]</span>
<span class="sd"> * Iterator[T]</span>
<span class="sd"> * Generator[T]</span>
<span class="sd">Type-hints can be nested, allowing one to define type-hints for complex types:</span>
<span class="sd"> * &#39;List[Tuple[int, int, str]]</span>
<span class="sd">In addition, type-hints can be used to implement run-time type-checking via the</span>
<span class="sd">&#39;type_check&#39; method on each TypeConstraint.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="c1"># pytype: skip-file</span>
<span class="kn">import</span> <span class="nn">copy</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">types</span>
<span class="kn">import</span> <span class="nn">typing</span>
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">abc</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
<span class="s1">&#39;Any&#39;</span><span class="p">,</span>
<span class="s1">&#39;Union&#39;</span><span class="p">,</span>
<span class="s1">&#39;Optional&#39;</span><span class="p">,</span>
<span class="s1">&#39;Tuple&#39;</span><span class="p">,</span>
<span class="s1">&#39;List&#39;</span><span class="p">,</span>
<span class="s1">&#39;KV&#39;</span><span class="p">,</span>
<span class="s1">&#39;Dict&#39;</span><span class="p">,</span>
<span class="s1">&#39;Set&#39;</span><span class="p">,</span>
<span class="s1">&#39;FrozenSet&#39;</span><span class="p">,</span>
<span class="s1">&#39;Iterable&#39;</span><span class="p">,</span>
<span class="s1">&#39;Iterator&#39;</span><span class="p">,</span>
<span class="s1">&#39;Generator&#39;</span><span class="p">,</span>
<span class="s1">&#39;WindowedValue&#39;</span><span class="p">,</span>
<span class="s1">&#39;TypeVariable&#39;</span><span class="p">,</span>
<span class="p">]</span>
<span class="c1"># A set of the built-in Python types we don&#39;t support, guiding the users</span>
<span class="c1"># to templated (upper-case) versions instead.</span>
<span class="n">DISALLOWED_PRIMITIVE_TYPES</span> <span class="o">=</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">set</span><span class="p">,</span> <span class="nb">frozenset</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)</span>
<span class="n">_LOGGER</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">SimpleTypeHintError</span><span class="p">(</span><span class="ne">TypeError</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">CompositeTypeHintError</span><span class="p">(</span><span class="ne">TypeError</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">GetitemConstructor</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;A metaclass that makes Cls[arg] an alias for Cls(arg).&quot;&quot;&quot;</span>
<span class="k">def</span> <span class="fm">__getitem__</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="bp">cls</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">TypeConstraint</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;The base-class for all created type-constraints defined below.</span>
<span class="sd"> A :class:`TypeConstraint` is the result of parameterizing a</span>
<span class="sd"> :class:`CompositeTypeHint` with with one of the allowed Python types or</span>
<span class="sd"> another :class:`CompositeTypeHint`. It binds and enforces a specific</span>
<span class="sd"> version of a generalized TypeHint.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">_consistent_with_check_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sub</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns whether sub is consistent with self.</span>
<span class="sd"> Has the same relationship to is_consistent_with() as</span>
<span class="sd"> __subclasscheck__ does for issubclass().</span>
<span class="sd"> Not meant to be called directly; call is_consistent_with(sub, self)</span>
<span class="sd"> instead.</span>
<span class="sd"> Implementation may assume that maybe_sub_type is not Any</span>
<span class="sd"> and has been normalized.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">raise</span> <span class="ne">NotImplementedError</span>
<span class="k">def</span> <span class="nf">type_check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Determines if the type of &#39;instance&#39; satisfies this type constraint.</span>
<span class="sd"> Args:</span>
<span class="sd"> instance: An instance of a Python object.</span>
<span class="sd"> Raises:</span>
<span class="sd"> :class:`TypeError`: The passed **instance** doesn&#39;t satisfy</span>
<span class="sd"> this :class:`TypeConstraint`. Subclasses of</span>
<span class="sd"> :class:`TypeConstraint` are free to raise any of the subclasses of</span>
<span class="sd"> :class:`TypeError` defined above, depending on</span>
<span class="sd"> the manner of the type hint error.</span>
<span class="sd"> All :class:`TypeConstraint` sub-classes must define this method in other</span>
<span class="sd"> for the class object to be created.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">raise</span> <span class="ne">NotImplementedError</span>
<span class="k">def</span> <span class="nf">match_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">unused_concrete_type</span><span class="p">):</span>
<span class="k">return</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">bind_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">unused_bindings</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">def</span> <span class="nf">_inner_types</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Iterates over the inner types of the composite type.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">[]</span>
<span class="k">def</span> <span class="nf">visit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">visitor</span><span class="p">,</span> <span class="n">visitor_arg</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Visitor method to visit all inner types of a composite type.</span>
<span class="sd"> Args:</span>
<span class="sd"> visitor: A callable invoked for all nodes in the type tree comprising</span>
<span class="sd"> a composite type. The visitor will be called with the node visited</span>
<span class="sd"> and the visitor argument specified here.</span>
<span class="sd"> visitor_arg: Visitor callback second argument.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">visitor</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">visitor_arg</span><span class="p">)</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_inner_types</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">TypeConstraint</span><span class="p">):</span>
<span class="n">t</span><span class="o">.</span><span class="n">visit</span><span class="p">(</span><span class="n">visitor</span><span class="p">,</span> <span class="n">visitor_arg</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">visitor</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">visitor_arg</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">visit_inner_types</span><span class="p">(</span><span class="n">type_constraint</span><span class="p">,</span> <span class="n">visitor</span><span class="p">,</span> <span class="n">visitor_arg</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Visitor pattern to visit all inner types of a type constraint.</span>
<span class="sd"> Args:</span>
<span class="sd"> type_constraint: A type constraint or a type.</span>
<span class="sd"> visitor: A callable invoked for all nodes in the type tree comprising a</span>
<span class="sd"> composite type. The visitor will be called with the node visited and the</span>
<span class="sd"> visitor argument specified here.</span>
<span class="sd"> visitor_arg: Visitor callback second argument.</span>
<span class="sd"> Note:</span>
<span class="sd"> Raise and capture a StopIteration to terminate the visit, e.g.</span>
<span class="sd"> ```</span>
<span class="sd"> def visitor(type_constraint, visitor_arg):</span>
<span class="sd"> if ...:</span>
<span class="sd"> raise StopIteration</span>
<span class="sd"> try:</span>
<span class="sd"> visit_inner_types(type_constraint, visitor, visitor_arg)</span>
<span class="sd"> except StopIteration:</span>
<span class="sd"> pass</span>
<span class="sd"> ```</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">type_constraint</span><span class="p">,</span> <span class="n">TypeConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="n">type_constraint</span><span class="o">.</span><span class="n">visit</span><span class="p">(</span><span class="n">visitor</span><span class="p">,</span> <span class="n">visitor_arg</span><span class="p">)</span>
<span class="k">return</span> <span class="n">visitor</span><span class="p">(</span><span class="n">type_constraint</span><span class="p">,</span> <span class="n">visitor_arg</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">match_type_variables</span><span class="p">(</span><span class="n">type_constraint</span><span class="p">,</span> <span class="n">concrete_type</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">type_constraint</span><span class="p">,</span> <span class="n">TypeConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="n">type_constraint</span><span class="o">.</span><span class="n">match_type_variables</span><span class="p">(</span><span class="n">concrete_type</span><span class="p">)</span>
<span class="k">return</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">bind_type_variables</span><span class="p">(</span><span class="n">type_constraint</span><span class="p">,</span> <span class="n">bindings</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">type_constraint</span><span class="p">,</span> <span class="n">TypeConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="n">type_constraint</span><span class="o">.</span><span class="n">bind_type_variables</span><span class="p">(</span><span class="n">bindings</span><span class="p">)</span>
<span class="k">return</span> <span class="n">type_constraint</span>
<span class="k">class</span> <span class="nc">IndexableTypeConstraint</span><span class="p">(</span><span class="n">TypeConstraint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;An internal common base-class for all type constraints with indexing.</span>
<span class="sd"> E.G. SequenceTypeConstraint + Tuple&#39;s of fixed size.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">_constraint_for_index</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">idx</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns the type at the given index. This is used to allow type inference</span>
<span class="sd"> to determine the correct type for a specific index. On lists this will also</span>
<span class="sd"> be the same, however for tuples the value will depend on the position. This</span>
<span class="sd"> was added as part of the futurize changes since more of the expressions now</span>
<span class="sd"> index into tuples.&quot;&quot;&quot;</span>
<span class="k">raise</span> <span class="ne">NotImplementedError</span>
<span class="k">class</span> <span class="nc">SequenceTypeConstraint</span><span class="p">(</span><span class="n">IndexableTypeConstraint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;A common base-class for all sequence related type-constraint classes.</span>
<span class="sd"> A sequence is defined as an arbitrary length homogeneous container type. Type</span>
<span class="sd"> hints which fall under this category include: List[T], Set[T], Iterable[T],</span>
<span class="sd"> and Tuple[T, ...].</span>
<span class="sd"> Sub-classes may need to override &#39;_consistent_with_check_&#39; if a particular</span>
<span class="sd"> sequence requires special handling with respect to type compatibility.</span>
<span class="sd"> Attributes:</span>
<span class="sd"> inner_type: The type which every element in the sequence should be an</span>
<span class="sd"> instance of.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inner_type</span><span class="p">,</span> <span class="n">sequence_type</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span> <span class="o">=</span> <span class="n">normalize</span><span class="p">(</span><span class="n">inner_type</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sequence_type</span> <span class="o">=</span> <span class="n">sequence_type</span>
<span class="k">def</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">return</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">SequenceTypeConstraint</span><span class="p">)</span> <span class="ow">and</span>
<span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">==</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">inner_type</span><span class="p">)</span>
<span class="k">def</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">inner_type</span><span class="p">)</span> <span class="o">^</span> <span class="mi">13</span> <span class="o">*</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_inner_types</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span>
<span class="k">def</span> <span class="nf">_constraint_for_index</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">idx</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns the type at the given index.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span>
<span class="k">def</span> <span class="nf">_consistent_with_check_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sub</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span> <span class="ow">and</span>
<span class="n">is_consistent_with</span><span class="p">(</span><span class="n">sub</span><span class="o">.</span><span class="n">inner_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">type_check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sequence_instance</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">sequence_instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sequence_type</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> type-constraint violated. Valid object instance &quot;</span>
<span class="s2">&quot;must be of type &#39;</span><span class="si">%s</span><span class="s2">&#39;. Instead, an instance of &#39;</span><span class="si">%s</span><span class="s2">&#39; &quot;</span>
<span class="s2">&quot;was received.&quot;</span> <span class="o">%</span> <span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sequence_type</span><span class="o">.</span><span class="vm">__name__</span><span class="o">.</span><span class="n">title</span><span class="p">(),</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sequence_type</span><span class="o">.</span><span class="vm">__name__</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span>
<span class="n">sequence_instance</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
<span class="k">for</span> <span class="n">index</span><span class="p">,</span> <span class="n">elem</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">sequence_instance</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">check_constraint</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">,</span> <span class="n">elem</span><span class="p">)</span>
<span class="k">except</span> <span class="n">SimpleTypeHintError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> hint type-constraint violated. The type of element #</span><span class="si">%s</span><span class="s1"> in &#39;</span>
<span class="s1">&#39;the passed </span><span class="si">%s</span><span class="s1"> is incorrect. Expected an instance of type </span><span class="si">%s</span><span class="s1">, &#39;</span>
<span class="s1">&#39;instead received an instance of type </span><span class="si">%s</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span>
<span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span>
<span class="n">index</span><span class="p">,</span>
<span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_sequence_type</span><span class="p">),</span>
<span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">),</span>
<span class="n">elem</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
<span class="k">except</span> <span class="n">CompositeTypeHintError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> hint type-constraint violated. The type of element #</span><span class="si">%s</span><span class="s1"> in &#39;</span>
<span class="s1">&#39;the passed </span><span class="si">%s</span><span class="s1"> is incorrect: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span>
<span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="n">index</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sequence_type</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">e</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">match_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">concrete_type</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">concrete_type</span><span class="p">,</span> <span class="n">SequenceTypeConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="n">match_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">,</span> <span class="n">concrete_type</span><span class="o">.</span><span class="n">inner_type</span><span class="p">)</span>
<span class="k">return</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">bind_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bindings</span><span class="p">):</span>
<span class="n">bound_inner_type</span> <span class="o">=</span> <span class="n">bind_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">,</span> <span class="n">bindings</span><span class="p">)</span>
<span class="k">if</span> <span class="n">bound_inner_type</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="n">bound_self</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="n">bound_self</span><span class="o">.</span><span class="n">inner_type</span> <span class="o">=</span> <span class="n">bound_inner_type</span>
<span class="k">return</span> <span class="n">bound_self</span>
<span class="k">class</span> <span class="nc">CompositeTypeHint</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;The base-class for all created type-hint classes defined below.</span>
<span class="sd"> CompositeTypeHint&#39;s serve primarily as TypeConstraint factories. They are</span>
<span class="sd"> only required to define a single method: &#39;__getitem__&#39; which should return a</span>
<span class="sd"> parameterized TypeConstraint, that can be used to enforce static or run-time</span>
<span class="sd"> type-checking.</span>
<span class="sd"> &#39;__getitem__&#39; is used as a factory function in order to provide a familiar</span>
<span class="sd"> API for defining type-hints. The ultimate result is that one will be able to</span>
<span class="sd"> use: CompositeTypeHint[type_parameter] to create a type-hint object that</span>
<span class="sd"> behaves like any other Python object. This allows one to create</span>
<span class="sd"> &#39;type-aliases&#39; by assigning the returned type-hints to a variable.</span>
<span class="sd"> * Example: &#39;Coordinates = List[Tuple[int, int]]&#39;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">__getitem___</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">py_type</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Given a type creates a TypeConstraint instance parameterized by the type.</span>
<span class="sd"> This function serves as a factory function which creates TypeConstraint</span>
<span class="sd"> instances. Additionally, implementations by sub-classes should perform any</span>
<span class="sd"> sanity checking of the passed types in this method in order to rule-out</span>
<span class="sd"> disallowed behavior. Such as, attempting to create a TypeConstraint whose</span>
<span class="sd"> parameterized type is actually an object instance.</span>
<span class="sd"> Args:</span>
<span class="sd"> py_type: An instance of a Python type or TypeConstraint.</span>
<span class="sd"> Returns: An instance of a custom TypeConstraint for this CompositeTypeHint.</span>
<span class="sd"> Raises:</span>
<span class="sd"> TypeError: If the passed type violates any contraints for this particular</span>
<span class="sd"> TypeHint.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">raise</span> <span class="ne">NotImplementedError</span>
<span class="k">def</span> <span class="nf">is_typing_generic</span><span class="p">(</span><span class="n">type_param</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Determines if an object is a subscripted typing.Generic type, such as</span>
<span class="sd"> PCollection[int].</span>
<span class="sd"> Such objects are considered valid type parameters.</span>
<span class="sd"> Always returns false for Python versions below 3.7.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">typing</span><span class="p">,</span> <span class="s1">&#39;_GenericAlias&#39;</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">type_param</span><span class="p">,</span> <span class="n">typing</span><span class="o">.</span><span class="n">_GenericAlias</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">def</span> <span class="nf">validate_composite_type_param</span><span class="p">(</span><span class="n">type_param</span><span class="p">,</span> <span class="n">error_msg_prefix</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Determines if an object is a valid type parameter to a</span>
<span class="sd"> :class:`CompositeTypeHint`.</span>
<span class="sd"> Implements sanity checking to disallow things like::</span>
<span class="sd"> List[1, 2, 3] or Dict[5].</span>
<span class="sd"> Args:</span>
<span class="sd"> type_param: An object instance.</span>
<span class="sd"> error_msg_prefix (:class:`str`): A string prefix used to format an error</span>
<span class="sd"> message in the case of an exception.</span>
<span class="sd"> Raises:</span>
<span class="sd"> TypeError: If the passed **type_param** is not a valid type</span>
<span class="sd"> parameter for a :class:`CompositeTypeHint`.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Must either be a TypeConstraint instance or a basic Python type.</span>
<span class="n">possible_classes</span> <span class="o">=</span> <span class="p">[</span><span class="nb">type</span><span class="p">,</span> <span class="n">TypeConstraint</span><span class="p">]</span>
<span class="n">is_not_type_constraint</span> <span class="o">=</span> <span class="p">(</span>
<span class="ow">not</span> <span class="n">is_typing_generic</span><span class="p">(</span><span class="n">type_param</span><span class="p">)</span> <span class="ow">and</span>
<span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">type_param</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">possible_classes</span><span class="p">))</span> <span class="ow">and</span>
<span class="n">type_param</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span>
<span class="nb">getattr</span><span class="p">(</span><span class="n">type_param</span><span class="p">,</span> <span class="s1">&#39;__module__&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="o">!=</span> <span class="s1">&#39;typing&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="o">.</span><span class="n">major</span> <span class="o">==</span> <span class="mi">3</span> <span class="ow">and</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="o">.</span><span class="n">minor</span> <span class="o">&gt;=</span> <span class="mi">10</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">type_param</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">is_not_type_constraint</span> <span class="o">=</span> <span class="kc">False</span>
<span class="c1"># Pre-Python 3.9 compositve type-hinting with built-in types was not</span>
<span class="c1"># supported, the typing module equivalents should be used instead.</span>
<span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="o">.</span><span class="n">major</span> <span class="o">==</span> <span class="mi">3</span> <span class="ow">and</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="o">.</span><span class="n">minor</span> <span class="o">&lt;</span> <span class="mi">9</span><span class="p">:</span>
<span class="n">is_not_type_constraint</span> <span class="o">=</span> <span class="n">is_not_type_constraint</span> <span class="ow">or</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">type_param</span><span class="p">,</span> <span class="nb">type</span><span class="p">)</span> <span class="ow">and</span>
<span class="n">type_param</span> <span class="ow">in</span> <span class="n">DISALLOWED_PRIMITIVE_TYPES</span><span class="p">)</span>
<span class="k">if</span> <span class="n">is_not_type_constraint</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
<span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> must be a non-sequence, a type, or a TypeConstraint. </span><span class="si">%s</span><span class="s1">&#39;</span>
<span class="s1">&#39; is an instance of </span><span class="si">%s</span><span class="s1">.&#39;</span> <span class="o">%</span>
<span class="p">(</span><span class="n">error_msg_prefix</span><span class="p">,</span> <span class="n">type_param</span><span class="p">,</span> <span class="n">type_param</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">check_constraint</span><span class="p">(</span><span class="n">type_constraint</span><span class="p">,</span> <span class="n">object_instance</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Determine if the passed type instance satisfies the TypeConstraint.</span>
<span class="sd"> When examining a candidate type for constraint satisfaction in</span>
<span class="sd"> &#39;type_check&#39;, all CompositeTypeHint&#39;s eventually call this function. This</span>
<span class="sd"> function may end up being called recursively if the hinted type of a</span>
<span class="sd"> CompositeTypeHint is another CompositeTypeHint.</span>
<span class="sd"> Args:</span>
<span class="sd"> type_constraint: An instance of a TypeConstraint or a built-in Python type.</span>
<span class="sd"> object_instance: An object instance.</span>
<span class="sd"> Raises:</span>
<span class="sd"> SimpleTypeHintError: If &#39;type_constraint&#39; is a one of the allowed primitive</span>
<span class="sd"> Python types and &#39;object_instance&#39; isn&#39;t an instance of this type.</span>
<span class="sd"> CompositeTypeHintError: If &#39;type_constraint&#39; is a TypeConstraint object and</span>
<span class="sd"> &#39;object_instance&#39; does not satisfy its constraint.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">type_constraint</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">object_instance</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">type_constraint</span><span class="p">,</span> <span class="n">TypeConstraint</span><span class="p">):</span>
<span class="n">type_constraint</span><span class="o">.</span><span class="n">type_check</span><span class="p">(</span><span class="n">object_instance</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">type_constraint</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="c1"># TODO(robertwb): Fix uses of None for Any.</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">type_constraint</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;bad type: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">type_constraint</span><span class="p">,</span> <span class="p">))</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">object_instance</span><span class="p">,</span> <span class="n">type_constraint</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">SimpleTypeHintError</span>
<span class="k">class</span> <span class="nc">AnyTypeConstraint</span><span class="p">(</span><span class="n">TypeConstraint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;An Any type-hint.</span>
<span class="sd"> Any is intended to be used as a &quot;don&#39;t care&quot; when hinting the types of</span>
<span class="sd"> function arguments or return types. All other TypeConstraint&#39;s are equivalent</span>
<span class="sd"> to &#39;Any&#39;, and its &#39;type_check&#39; method is a no-op.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</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">return</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">==</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">def</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">&#39;Any&#39;</span>
<span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># TODO(https://github.com/apache/beam/issues/18633): Fix</span>
<span class="c1"># typehints.TypeVariable issues with __hash__.</span>
<span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">id</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">type_check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span>
<span class="k">pass</span>
<div class="viewcode-block" id="TypeVariable"><a class="viewcode-back" href="../../../apache_beam.typehints.typehints.html#apache_beam.typehints.typehints.TypeVariable">[docs]</a><span class="k">class</span> <span class="nc">TypeVariable</span><span class="p">(</span><span class="n">AnyTypeConstraint</span><span class="p">):</span>
<span class="k">def</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">use_name_in_eq</span><span class="o">=</span><span class="kc">True</span><span class="p">):</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">use_name_in_eq</span> <span class="o">=</span> <span class="n">use_name_in_eq</span>
<span class="k">def</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="c1"># The &quot;other&quot; may be an Ellipsis object</span>
<span class="c1"># so we have to check if it has use_name_in_eq first</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">use_name_in_eq</span> <span class="ow">and</span> <span class="p">(</span><span class="nb">hasattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="s1">&#39;use_name_in_eq&#39;</span><span class="p">)</span> <span class="ow">and</span>
<span class="n">other</span><span class="o">.</span><span class="n">use_name_in_eq</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">==</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">name</span>
<span class="k">return</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">==</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># TODO(https://github.com/apache/beam/issues/18633): Fix</span>
<span class="c1"># typehints.TypeVariable issues with __hash__.</span>
<span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">id</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="k">def</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">&#39;TypeVariable[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
<div class="viewcode-block" id="TypeVariable.match_type_variables"><a class="viewcode-back" href="../../../apache_beam.typehints.typehints.html#apache_beam.typehints.typehints.TypeVariable.match_type_variables">[docs]</a> <span class="k">def</span> <span class="nf">match_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">concrete_type</span><span class="p">):</span>
<span class="k">return</span> <span class="p">{</span><span class="bp">self</span><span class="p">:</span> <span class="n">concrete_type</span><span class="p">}</span></div>
<div class="viewcode-block" id="TypeVariable.bind_type_variables"><a class="viewcode-back" href="../../../apache_beam.typehints.typehints.html#apache_beam.typehints.typehints.TypeVariable.bind_type_variables">[docs]</a> <span class="k">def</span> <span class="nf">bind_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bindings</span><span class="p">):</span>
<span class="k">return</span> <span class="n">bindings</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="c1"># Star matches all type variables.</span>
<span class="n">bindings</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span></div></div>
<span class="k">class</span> <span class="nc">UnionHint</span><span class="p">(</span><span class="n">CompositeTypeHint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;A Union type-hint. Union[X, Y] accepts instances of type X OR type Y.</span>
<span class="sd"> Duplicate type parameters are ignored. Additonally, Nested Union hints will</span>
<span class="sd"> be flattened out. For example:</span>
<span class="sd"> * Union[Union[str, int], bool] -&gt; Union[str, int, bool]</span>
<span class="sd"> A candidate type instance satisfies a UnionConstraint if it is an</span>
<span class="sd"> instance of any of the parameterized &#39;union_types&#39; for a Union.</span>
<span class="sd"> Union[X] is disallowed, and all type parameters will be sanity checked to</span>
<span class="sd"> ensure compatibility with nested type-hints.</span>
<span class="sd"> When comparing two Union hints, ordering is enforced before comparison.</span>
<span class="sd"> * Union[int, str] == Union[str, int]</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">class</span> <span class="nc">UnionConstraint</span><span class="p">(</span><span class="n">TypeConstraint</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">union_types</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">union_types</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">normalize</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">union_types</span><span class="p">)</span>
<span class="k">def</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">return</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">UnionHint</span><span class="o">.</span><span class="n">UnionConstraint</span><span class="p">)</span> <span class="ow">and</span>
<span class="bp">self</span><span class="o">.</span><span class="n">union_types</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">union_types</span><span class="p">)</span>
<span class="k">def</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="mi">1</span> <span class="o">+</span> <span class="nb">sum</span><span class="p">(</span><span class="nb">hash</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="bp">self</span><span class="o">.</span><span class="n">union_types</span><span class="p">)</span>
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># Sorting the type name strings simplifies unit tests.</span>
<span class="k">return</span> <span class="s1">&#39;Union[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="p">(</span>
<span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="nb">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="bp">self</span><span class="o">.</span><span class="n">union_types</span><span class="p">)))</span>
<span class="k">def</span> <span class="nf">inner_types</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">union_types</span><span class="p">:</span>
<span class="k">yield</span> <span class="n">t</span>
<span class="k">def</span> <span class="nf">contains_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">maybe_type</span><span class="p">):</span>
<span class="k">return</span> <span class="n">maybe_type</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">union_types</span>
<span class="k">def</span> <span class="nf">_consistent_with_check_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sub</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="n">UnionConstraint</span><span class="p">):</span>
<span class="c1"># A union type is compatible if every possible type is compatible.</span>
<span class="c1"># E.g. Union[A, B, C] &gt; Union[A, B].</span>
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span><span class="n">is_consistent_with</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span> <span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">sub</span><span class="o">.</span><span class="n">union_types</span><span class="p">)</span>
<span class="c1"># Other must be compatible with at least one of this union&#39;s subtypes.</span>
<span class="c1"># E.g. Union[A, B, C] &gt; T if T &gt; A or T &gt; B or T &gt; C.</span>
<span class="k">return</span> <span class="nb">any</span><span class="p">(</span><span class="n">is_consistent_with</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="n">elem</span><span class="p">)</span> <span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">union_types</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">type_check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span>
<span class="n">error_msg</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">union_types</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">check_constraint</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">instance</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">except</span> <span class="ne">TypeError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">error_msg</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<span class="k">continue</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> type-constraint violated. Expected an instance of one of: </span><span class="si">%s</span><span class="s1">, &#39;</span>
<span class="s1">&#39;received </span><span class="si">%s</span><span class="s1"> instead.</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span>
<span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span>
<span class="nb">tuple</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="nb">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="bp">self</span><span class="o">.</span><span class="n">union_types</span><span class="p">)),</span>
<span class="n">instance</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
<span class="n">error_msg</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">match_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">concrete_type</span><span class="p">):</span>
<span class="n">sub_bindings</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">match_type_variables</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">concrete_type</span><span class="p">)</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">union_types</span>
<span class="k">if</span> <span class="n">is_consistent_with</span><span class="p">(</span><span class="n">concrete_type</span><span class="p">,</span> <span class="n">t</span><span class="p">)</span>
<span class="p">]</span>
<span class="k">if</span> <span class="n">sub_bindings</span><span class="p">:</span>
<span class="k">return</span> <span class="p">{</span>
<span class="n">var</span><span class="p">:</span> <span class="n">Union</span><span class="p">[(</span><span class="n">sub</span><span class="p">[</span><span class="n">var</span><span class="p">]</span> <span class="k">for</span> <span class="n">sub</span> <span class="ow">in</span> <span class="n">sub_bindings</span><span class="p">)]</span>
<span class="k">for</span> <span class="n">var</span> <span class="ow">in</span> <span class="nb">set</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span>
<span class="o">*</span><span class="p">[</span><span class="nb">set</span><span class="p">(</span><span class="n">sub</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> <span class="k">for</span> <span class="n">sub</span> <span class="ow">in</span> <span class="n">sub_bindings</span><span class="p">])</span>
<span class="p">}</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">bind_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bindings</span><span class="p">):</span>
<span class="k">return</span> <span class="n">Union</span><span class="p">[(</span><span class="n">bind_type_variables</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">bindings</span><span class="p">)</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">union_types</span><span class="p">)]</span>
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_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">type_params</span><span class="p">,</span> <span class="p">(</span><span class="n">abc</span><span class="o">.</span><span class="n">Iterable</span><span class="p">,</span> <span class="nb">set</span><span class="p">)):</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot create Union without a sequence of types.&#39;</span><span class="p">)</span>
<span class="c1"># Flatten nested Union&#39;s and duplicated repeated type hints.</span>
<span class="n">params</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="n">dict_union</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">type_params</span><span class="p">:</span>
<span class="n">validate_composite_type_param</span><span class="p">(</span>
<span class="n">t</span><span class="p">,</span> <span class="n">error_msg_prefix</span><span class="o">=</span><span class="s1">&#39;All parameters to a Union hint&#39;</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="bp">self</span><span class="o">.</span><span class="n">UnionConstraint</span><span class="p">):</span>
<span class="n">params</span> <span class="o">|=</span> <span class="n">t</span><span class="o">.</span><span class="n">union_types</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="n">DictConstraint</span><span class="p">):</span>
<span class="k">if</span> <span class="n">dict_union</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">dict_union</span> <span class="o">=</span> <span class="n">t</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">dict_union</span><span class="o">.</span><span class="n">key_type</span> <span class="o">=</span> <span class="n">Union</span><span class="p">[</span><span class="n">dict_union</span><span class="o">.</span><span class="n">key_type</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">key_type</span><span class="p">]</span>
<span class="n">dict_union</span><span class="o">.</span><span class="n">value_type</span> <span class="o">=</span> <span class="n">Union</span><span class="p">[</span><span class="n">dict_union</span><span class="o">.</span><span class="n">value_type</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">value_type</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">add</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>
<span class="k">if</span> <span class="n">dict_union</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">params</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">dict_union</span><span class="p">)</span>
<span class="k">if</span> <span class="n">Any</span> <span class="ow">in</span> <span class="n">params</span><span class="p">:</span>
<span class="k">return</span> <span class="n">Any</span>
<span class="k">elif</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="p">:</span>
<span class="k">return</span> <span class="nb">next</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</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">UnionConstraint</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
<span class="n">UnionConstraint</span> <span class="o">=</span> <span class="n">UnionHint</span><span class="o">.</span><span class="n">UnionConstraint</span>
<span class="k">class</span> <span class="nc">OptionalHint</span><span class="p">(</span><span class="n">UnionHint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;An Option type-hint. Optional[X] accepts instances of X or None.</span>
<span class="sd"> The Optional[X] factory function proxies to Union[X, type(None)]</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">py_type</span><span class="p">):</span>
<span class="c1"># A single type must have been passed.</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">py_type</span><span class="p">,</span> <span class="n">abc</span><span class="o">.</span><span class="n">Sequence</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
<span class="s1">&#39;An Option type-hint only accepts a single type &#39;</span>
<span class="s1">&#39;parameter.&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="n">py_type</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="k">def</span> <span class="nf">is_nullable</span><span class="p">(</span><span class="n">typehint</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">typehint</span><span class="p">,</span> <span class="n">UnionConstraint</span><span class="p">)</span> <span class="ow">and</span>
<span class="n">typehint</span><span class="o">.</span><span class="n">contains_type</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="ow">and</span>
<span class="nb">len</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">typehint</span><span class="o">.</span><span class="n">inner_types</span><span class="p">()))</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get_concrete_type_from_nullable</span><span class="p">(</span><span class="n">typehint</span><span class="p">):</span>
<span class="k">if</span> <span class="n">is_nullable</span><span class="p">(</span><span class="n">typehint</span><span class="p">):</span>
<span class="k">for</span> <span class="n">inner_type</span> <span class="ow">in</span> <span class="n">typehint</span><span class="o">.</span><span class="n">inner_types</span><span class="p">():</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">type</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span> <span class="o">==</span> <span class="n">inner_type</span><span class="p">:</span>
<span class="k">return</span> <span class="n">inner_type</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">&#39;Typehint is not of nullable type&#39;</span><span class="p">,</span> <span class="n">typehint</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">TupleHint</span><span class="p">(</span><span class="n">CompositeTypeHint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;A Tuple type-hint.</span>
<span class="sd"> Tuple can accept 1 or more type-hint parameters.</span>
<span class="sd"> Tuple[X, Y] represents a tuple of *exactly* two elements, with the first</span>
<span class="sd"> being of type &#39;X&#39; and the second an instance of type &#39;Y&#39;.</span>
<span class="sd"> * (1, 2) satisfies Tuple[int, int]</span>
<span class="sd"> Additionally, one is able to type-hint an arbitary length, homogeneous tuple</span>
<span class="sd"> by passing the Ellipsis (...) object as the second parameter.</span>
<span class="sd"> As an example, Tuple[str, ...] indicates a tuple of any length with each</span>
<span class="sd"> element being an instance of &#39;str&#39;.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">class</span> <span class="nc">TupleSequenceConstraint</span><span class="p">(</span><span class="n">SequenceTypeConstraint</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_param</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">type_param</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span>
<span class="k">def</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">&#39;Tuple[</span><span class="si">%s</span><span class="s1">, ...]&#39;</span> <span class="o">%</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_consistent_with_check_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sub</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="n">TupleConstraint</span><span class="p">):</span>
<span class="c1"># E.g. Tuple[A, B] &lt; Tuple[C, ...] iff A &lt; C and B &lt; C.</span>
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span>
<span class="n">is_consistent_with</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">)</span>
<span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">sub</span><span class="o">.</span><span class="n">tuple_types</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">_consistent_with_check_</span><span class="p">(</span><span class="n">sub</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">TupleConstraint</span><span class="p">(</span><span class="n">IndexableTypeConstraint</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_params</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tuple_types</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">normalize</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">type_params</span><span class="p">)</span>
<span class="k">def</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">return</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">TupleHint</span><span class="o">.</span><span class="n">TupleConstraint</span><span class="p">)</span> <span class="ow">and</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tuple_types</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">)</span>
<span class="k">def</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">tuple_types</span><span class="p">)</span>
<span class="k">def</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">&#39;Tuple[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="s1">&#39;, &#39;</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">t</span><span class="p">)</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_inner_types</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">:</span>
<span class="k">yield</span> <span class="n">t</span>
<span class="k">def</span> <span class="nf">_constraint_for_index</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">idx</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns the type at the given index.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">_consistent_with_check_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sub</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span> <span class="ow">and</span>
<span class="nb">len</span><span class="p">(</span><span class="n">sub</span><span class="o">.</span><span class="n">tuple_types</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">tuple_types</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">all</span><span class="p">(</span>
<span class="n">is_consistent_with</span><span class="p">(</span><span class="n">sub_elem</span><span class="p">,</span> <span class="n">elem</span><span class="p">)</span> <span class="k">for</span> <span class="n">sub_elem</span><span class="p">,</span>
<span class="n">elem</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">sub</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">)))</span>
<span class="k">def</span> <span class="nf">type_check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tuple_instance</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">tuple_instance</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s2">&quot;Tuple type constraint violated. Valid object instance must be of &quot;</span>
<span class="s2">&quot;type &#39;tuple&#39;. Instead, an instance of &#39;</span><span class="si">%s</span><span class="s2">&#39; was received.&quot;</span> <span class="o">%</span>
<span class="n">tuple_instance</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">tuple_instance</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">tuple_types</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s1">&#39;Passed object instance is of the proper type, but differs in &#39;</span>
<span class="s1">&#39;length from the hinted type. Expected a tuple of length </span><span class="si">%s</span><span class="s1">, &#39;</span>
<span class="s1">&#39;received a tuple of length </span><span class="si">%s</span><span class="s1">.&#39;</span> <span class="o">%</span>
<span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">tuple_instance</span><span class="p">)))</span>
<span class="k">for</span> <span class="n">type_pos</span><span class="p">,</span> <span class="p">(</span><span class="n">expected</span><span class="p">,</span> <span class="n">actual</span><span class="p">)</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">,</span>
<span class="n">tuple_instance</span><span class="p">)):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">check_constraint</span><span class="p">(</span><span class="n">expected</span><span class="p">,</span> <span class="n">actual</span><span class="p">)</span>
<span class="k">continue</span>
<span class="k">except</span> <span class="n">SimpleTypeHintError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> hint type-constraint violated. The type of element #</span><span class="si">%s</span><span class="s1"> in &#39;</span>
<span class="s1">&#39;the passed tuple is incorrect. Expected an instance of &#39;</span>
<span class="s1">&#39;type </span><span class="si">%s</span><span class="s1">, instead received an instance of type </span><span class="si">%s</span><span class="s1">.&#39;</span> <span class="o">%</span>
<span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="n">type_pos</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">expected</span><span class="p">),</span> <span class="n">actual</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
<span class="k">except</span> <span class="n">CompositeTypeHintError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> hint type-constraint violated. The type of element #</span><span class="si">%s</span><span class="s1"> in &#39;</span>
<span class="s1">&#39;the passed tuple is incorrect. </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="n">type_pos</span><span class="p">,</span> <span class="n">e</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">match_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">concrete_type</span><span class="p">):</span>
<span class="n">bindings</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">concrete_type</span><span class="p">,</span> <span class="n">TupleConstraint</span><span class="p">):</span>
<span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">,</span> <span class="n">concrete_type</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">):</span>
<span class="n">bindings</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">match_type_variables</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">))</span>
<span class="k">return</span> <span class="n">bindings</span>
<span class="k">def</span> <span class="nf">bind_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bindings</span><span class="p">):</span>
<span class="n">bound_tuple_types</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span>
<span class="n">bind_type_variables</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">bindings</span><span class="p">)</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">)</span>
<span class="k">if</span> <span class="n">bound_tuple_types</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">return</span> <span class="n">Tuple</span><span class="p">[</span><span class="n">bound_tuple_types</span><span class="p">]</span>
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_params</span><span class="p">):</span>
<span class="n">ellipsis</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">type_params</span><span class="p">,</span> <span class="n">abc</span><span class="o">.</span><span class="n">Iterable</span><span class="p">):</span>
<span class="c1"># Special case for hinting tuples with arity-1.</span>
<span class="n">type_params</span> <span class="o">=</span> <span class="p">(</span><span class="n">type_params</span><span class="p">,</span> <span class="p">)</span>
<span class="k">if</span> <span class="n">type_params</span> <span class="ow">and</span> <span class="n">type_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="bp">Ellipsis</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">type_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="s1">&#39;Ellipsis can only be used to type-hint an arbitrary &#39;</span>
<span class="s1">&#39;length tuple of containing a single type: &#39;</span>
<span class="s1">&#39;Tuple[A, ...].&#39;</span><span class="p">)</span>
<span class="c1"># Tuple[A, ...] indicates an arbitary length homogeneous tuple.</span>
<span class="n">type_params</span> <span class="o">=</span> <span class="n">type_params</span><span class="p">[:</span><span class="mi">1</span><span class="p">]</span>
<span class="n">ellipsis</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">type_params</span><span class="p">:</span>
<span class="n">validate_composite_type_param</span><span class="p">(</span>
<span class="n">t</span><span class="p">,</span> <span class="n">error_msg_prefix</span><span class="o">=</span><span class="s1">&#39;All parameters to a Tuple hint&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">ellipsis</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">TupleSequenceConstraint</span><span class="p">(</span><span class="n">type_params</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">TupleConstraint</span><span class="p">(</span><span class="n">type_params</span><span class="p">)</span>
<span class="n">TupleConstraint</span> <span class="o">=</span> <span class="n">TupleHint</span><span class="o">.</span><span class="n">TupleConstraint</span>
<span class="n">TupleSequenceConstraint</span> <span class="o">=</span> <span class="n">TupleHint</span><span class="o">.</span><span class="n">TupleSequenceConstraint</span>
<span class="k">class</span> <span class="nc">ListHint</span><span class="p">(</span><span class="n">CompositeTypeHint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;A List type-hint.</span>
<span class="sd"> List[X] represents an instance of a list populated by a single homogeneous</span>
<span class="sd"> type. The parameterized type &#39;X&#39; can either be a built-in Python type or an</span>
<span class="sd"> instance of another TypeConstraint.</span>
<span class="sd"> * [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;] satisfies List[str]</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">class</span> <span class="nc">ListConstraint</span><span class="p">(</span><span class="n">SequenceTypeConstraint</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">list_type</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">list_type</span><span class="p">,</span> <span class="nb">list</span><span class="p">)</span>
<span class="k">def</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">&#39;List[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">)</span>
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">t</span><span class="p">):</span>
<span class="n">validate_composite_type_param</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">error_msg_prefix</span><span class="o">=</span><span class="s1">&#39;Parameter to List hint&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">ListConstraint</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>
<span class="n">ListConstraint</span> <span class="o">=</span> <span class="n">ListHint</span><span class="o">.</span><span class="n">ListConstraint</span>
<span class="k">class</span> <span class="nc">KVHint</span><span class="p">(</span><span class="n">CompositeTypeHint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;A KV type-hint, represents a Key-Value pair of a particular type.</span>
<span class="sd"> Internally, KV[X, Y] proxies to Tuple[X, Y]. A KV type-hint accepts only</span>
<span class="sd"> accepts exactly two type-parameters. The first represents the required</span>
<span class="sd"> key-type and the second the required value-type.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_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">type_params</span><span class="p">,</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="s1">&#39;Parameter to KV type-hint must be a tuple of types: &#39;</span>
<span class="s1">&#39;KV[.., ..].&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">type_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="s1">&#39;Length of parameters to a KV type-hint must be exactly 2. Passed &#39;</span>
<span class="s1">&#39;parameters: </span><span class="si">%s</span><span class="s1">, have a length of </span><span class="si">%s</span><span class="s1">.&#39;</span> <span class="o">%</span>
<span class="p">(</span><span class="n">type_params</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">type_params</span><span class="p">)))</span>
<span class="k">return</span> <span class="n">Tuple</span><span class="p">[</span><span class="n">type_params</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">key_value_types</span><span class="p">(</span><span class="n">kv</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns the key and value type of a KV type-hint.</span>
<span class="sd"> Args:</span>
<span class="sd"> kv: An instance of a TypeConstraint sub-class.</span>
<span class="sd"> Returns:</span>
<span class="sd"> A tuple: (key_type, value_type) if the passed type-hint is an instance of a</span>
<span class="sd"> KV type-hint, and (Any, Any) otherwise.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">kv</span><span class="p">,</span> <span class="n">TupleHint</span><span class="o">.</span><span class="n">TupleConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="n">kv</span><span class="o">.</span><span class="n">tuple_types</span>
<span class="k">return</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Any</span>
<span class="k">class</span> <span class="nc">DictHint</span><span class="p">(</span><span class="n">CompositeTypeHint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;A Dict type-hint.</span>
<span class="sd"> Dict[K, V] Represents a dictionary where all keys are of a particular type</span>
<span class="sd"> and all values are of another (possible the same) type.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">class</span> <span class="nc">DictConstraint</span><span class="p">(</span><span class="n">TypeConstraint</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key_type</span><span class="p">,</span> <span class="n">value_type</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">key_type</span> <span class="o">=</span> <span class="n">normalize</span><span class="p">(</span><span class="n">key_type</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">value_type</span> <span class="o">=</span> <span class="n">normalize</span><span class="p">(</span><span class="n">value_type</span><span class="p">)</span>
<span class="k">def</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">&#39;Dict[</span><span class="si">%s</span><span class="s1">, </span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">key_type</span><span class="p">),</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">value_type</span><span class="p">))</span>
<span class="k">def</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">return</span> <span class="p">(</span>
<span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">==</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">key_type</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">key_type</span> <span class="ow">and</span>
<span class="bp">self</span><span class="o">.</span><span class="n">value_type</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">value_type</span><span class="p">)</span>
<span class="k">def</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">type</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">key_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">value_type</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_inner_types</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">key_type</span>
<span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">value_type</span>
<span class="k">def</span> <span class="nf">_consistent_with_check_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sub</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span> <span class="ow">and</span>
<span class="n">is_consistent_with</span><span class="p">(</span><span class="n">sub</span><span class="o">.</span><span class="n">key_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">key_type</span><span class="p">)</span> <span class="ow">and</span>
<span class="n">is_consistent_with</span><span class="p">(</span><span class="n">sub</span><span class="o">.</span><span class="n">value_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">value_type</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_raise_hint_exception_or_inner_exception</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span> <span class="n">is_key</span><span class="p">,</span> <span class="n">incorrect_instance</span><span class="p">,</span> <span class="n">inner_error_message</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">):</span>
<span class="n">incorrect_type</span> <span class="o">=</span> <span class="s1">&#39;values&#39;</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">is_key</span> <span class="k">else</span> <span class="s1">&#39;keys&#39;</span>
<span class="n">hinted_type</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">value_type</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">is_key</span> <span class="k">else</span> <span class="bp">self</span><span class="o">.</span><span class="n">key_type</span>
<span class="k">if</span> <span class="n">inner_error_message</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> hint </span><span class="si">%s</span><span class="s1">-type constraint violated. All </span><span class="si">%s</span><span class="s1"> should be of type &#39;</span>
<span class="s1">&#39;</span><span class="si">%s</span><span class="s1">. Instead: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span>
<span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span>
<span class="n">incorrect_type</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span>
<span class="n">incorrect_type</span><span class="p">,</span>
<span class="nb">repr</span><span class="p">(</span><span class="n">hinted_type</span><span class="p">),</span>
<span class="n">inner_error_message</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> hint </span><span class="si">%s</span><span class="s1">-type constraint violated. All </span><span class="si">%s</span><span class="s1"> should be of &#39;</span>
<span class="s1">&#39;type </span><span class="si">%s</span><span class="s1">. Instead, </span><span class="si">%s</span><span class="s1"> is of type </span><span class="si">%s</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span>
<span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span>
<span class="n">incorrect_type</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span>
<span class="n">incorrect_type</span><span class="p">,</span>
<span class="nb">repr</span><span class="p">(</span><span class="n">hinted_type</span><span class="p">),</span>
<span class="n">incorrect_instance</span><span class="p">,</span>
<span class="n">incorrect_instance</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">type_check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dict_instance</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">dict_instance</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s1">&#39;Dict type-constraint violated. All passed instances must be of &#39;</span>
<span class="s1">&#39;type dict. </span><span class="si">%s</span><span class="s1"> is of type </span><span class="si">%s</span><span class="s1">.&#39;</span> <span class="o">%</span>
<span class="p">(</span><span class="n">dict_instance</span><span class="p">,</span> <span class="n">dict_instance</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">dict_instance</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">check_constraint</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">key_type</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
<span class="k">except</span> <span class="n">CompositeTypeHintError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_raise_hint_exception_or_inner_exception</span><span class="p">(</span><span class="kc">True</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">except</span> <span class="n">SimpleTypeHintError</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_raise_hint_exception_or_inner_exception</span><span class="p">(</span><span class="kc">True</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">check_constraint</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">value_type</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<span class="k">except</span> <span class="n">CompositeTypeHintError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_raise_hint_exception_or_inner_exception</span><span class="p">(</span><span class="kc">False</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">e</span><span class="p">))</span>
<span class="k">except</span> <span class="n">SimpleTypeHintError</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_raise_hint_exception_or_inner_exception</span><span class="p">(</span><span class="kc">False</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">match_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">concrete_type</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">concrete_type</span><span class="p">,</span> <span class="n">DictConstraint</span><span class="p">):</span>
<span class="n">bindings</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">bindings</span><span class="o">.</span><span class="n">update</span><span class="p">(</span>
<span class="n">match_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">key_type</span><span class="p">,</span> <span class="n">concrete_type</span><span class="o">.</span><span class="n">key_type</span><span class="p">))</span>
<span class="n">bindings</span><span class="o">.</span><span class="n">update</span><span class="p">(</span>
<span class="n">match_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">value_type</span><span class="p">,</span> <span class="n">concrete_type</span><span class="o">.</span><span class="n">value_type</span><span class="p">))</span>
<span class="k">return</span> <span class="n">bindings</span>
<span class="k">return</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">bind_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bindings</span><span class="p">):</span>
<span class="n">bound_key_type</span> <span class="o">=</span> <span class="n">bind_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">key_type</span><span class="p">,</span> <span class="n">bindings</span><span class="p">)</span>
<span class="n">bound_value_type</span> <span class="o">=</span> <span class="n">bind_type_variables</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">value_type</span><span class="p">,</span> <span class="n">bindings</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">bound_key_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">key_type</span><span class="p">)</span> <span class="o">==</span> <span class="p">(</span><span class="n">bound_value_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">value_type</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">return</span> <span class="n">Dict</span><span class="p">[</span><span class="n">bound_key_type</span><span class="p">,</span> <span class="n">bound_value_type</span><span class="p">]</span>
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_params</span><span class="p">):</span>
<span class="c1"># Type param must be a (k, v) pair.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">type_params</span><span class="p">,</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="s1">&#39;Parameter to Dict type-hint must be a tuple of types: &#39;</span>
<span class="s1">&#39;Dict[.., ..].&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">type_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="s1">&#39;Length of parameters to a Dict type-hint must be exactly 2. Passed &#39;</span>
<span class="s1">&#39;parameters: </span><span class="si">%s</span><span class="s1">, have a length of </span><span class="si">%s</span><span class="s1">.&#39;</span> <span class="o">%</span>
<span class="p">(</span><span class="n">type_params</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">type_params</span><span class="p">)))</span>
<span class="n">key_type</span><span class="p">,</span> <span class="n">value_type</span> <span class="o">=</span> <span class="n">type_params</span>
<span class="n">validate_composite_type_param</span><span class="p">(</span>
<span class="n">key_type</span><span class="p">,</span> <span class="n">error_msg_prefix</span><span class="o">=</span><span class="s1">&#39;Key-type parameter to a Dict hint&#39;</span><span class="p">)</span>
<span class="n">validate_composite_type_param</span><span class="p">(</span>
<span class="n">value_type</span><span class="p">,</span> <span class="n">error_msg_prefix</span><span class="o">=</span><span class="s1">&#39;Value-type parameter to a Dict hint&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">DictConstraint</span><span class="p">(</span><span class="n">key_type</span><span class="p">,</span> <span class="n">value_type</span><span class="p">)</span>
<span class="n">DictConstraint</span> <span class="o">=</span> <span class="n">DictHint</span><span class="o">.</span><span class="n">DictConstraint</span>
<span class="k">class</span> <span class="nc">SetHint</span><span class="p">(</span><span class="n">CompositeTypeHint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;A Set type-hint.</span>
<span class="sd"> Set[X] defines a type-hint for a set of homogeneous types. &#39;X&#39; may be either a</span>
<span class="sd"> built-in Python type or a another nested TypeConstraint.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">class</span> <span class="nc">SetTypeConstraint</span><span class="p">(</span><span class="n">SequenceTypeConstraint</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_param</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">type_param</span><span class="p">,</span> <span class="nb">set</span><span class="p">)</span>
<span class="k">def</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">&#39;Set[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">)</span>
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_param</span><span class="p">):</span>
<span class="n">validate_composite_type_param</span><span class="p">(</span>
<span class="n">type_param</span><span class="p">,</span> <span class="n">error_msg_prefix</span><span class="o">=</span><span class="s1">&#39;Parameter to a Set hint&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">SetTypeConstraint</span><span class="p">(</span><span class="n">type_param</span><span class="p">)</span>
<span class="n">SetTypeConstraint</span> <span class="o">=</span> <span class="n">SetHint</span><span class="o">.</span><span class="n">SetTypeConstraint</span>
<span class="k">class</span> <span class="nc">FrozenSetHint</span><span class="p">(</span><span class="n">CompositeTypeHint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;A FrozenSet type-hint.</span>
<span class="sd"> FrozenSet[X] defines a type-hint for a set of homogeneous types. &#39;X&#39; may be</span>
<span class="sd"> either a built-in Python type or a another nested TypeConstraint.</span>
<span class="sd"> This is a mirror copy of SetHint - consider refactoring common functionality.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">class</span> <span class="nc">FrozenSetTypeConstraint</span><span class="p">(</span><span class="n">SequenceTypeConstraint</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_param</span><span class="p">):</span>
<span class="nb">super</span><span class="p">(</span><span class="n">FrozenSetHint</span><span class="o">.</span><span class="n">FrozenSetTypeConstraint</span><span class="p">,</span>
<span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">type_param</span><span class="p">,</span> <span class="nb">frozenset</span><span class="p">)</span>
<span class="k">def</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">&#39;FrozenSet[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">)</span>
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_param</span><span class="p">):</span>
<span class="n">validate_composite_type_param</span><span class="p">(</span>
<span class="n">type_param</span><span class="p">,</span> <span class="n">error_msg_prefix</span><span class="o">=</span><span class="s1">&#39;Parameter to a FrozenSet hint&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">FrozenSetTypeConstraint</span><span class="p">(</span><span class="n">type_param</span><span class="p">)</span>
<span class="n">FrozenSetTypeConstraint</span> <span class="o">=</span> <span class="n">FrozenSetHint</span><span class="o">.</span><span class="n">FrozenSetTypeConstraint</span>
<span class="k">class</span> <span class="nc">IterableHint</span><span class="p">(</span><span class="n">CompositeTypeHint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;An Iterable type-hint.</span>
<span class="sd"> Iterable[X] defines a type-hint for an object implementing an &#39;__iter__&#39;</span>
<span class="sd"> method which yields objects which are all of the same type.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">class</span> <span class="nc">IterableTypeConstraint</span><span class="p">(</span><span class="n">SequenceTypeConstraint</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">iter_type</span><span class="p">):</span>
<span class="nb">super</span><span class="p">(</span><span class="n">IterableHint</span><span class="o">.</span><span class="n">IterableTypeConstraint</span><span class="p">,</span>
<span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">iter_type</span><span class="p">,</span> <span class="n">abc</span><span class="o">.</span><span class="n">Iterable</span><span class="p">)</span>
<span class="k">def</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">&#39;Iterable[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_consistent_with_check_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sub</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="n">SequenceTypeConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="n">is_consistent_with</span><span class="p">(</span><span class="n">sub</span><span class="o">.</span><span class="n">inner_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="n">TupleConstraint</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">sub</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">:</span>
<span class="c1"># The empty tuple is consistent with Iterator[T] for any T.</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="c1"># Each element in the hetrogenious tuple must be consistent with</span>
<span class="c1"># the iterator type.</span>
<span class="c1"># E.g. Tuple[A, B] &lt; Iterable[C] if A &lt; C and B &lt; C.</span>
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span>
<span class="n">is_consistent_with</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">)</span>
<span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">sub</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_param</span><span class="p">):</span>
<span class="n">validate_composite_type_param</span><span class="p">(</span>
<span class="n">type_param</span><span class="p">,</span> <span class="n">error_msg_prefix</span><span class="o">=</span><span class="s1">&#39;Parameter to an Iterable hint&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">IterableTypeConstraint</span><span class="p">(</span><span class="n">type_param</span><span class="p">)</span>
<span class="n">IterableTypeConstraint</span> <span class="o">=</span> <span class="n">IterableHint</span><span class="o">.</span><span class="n">IterableTypeConstraint</span>
<span class="k">class</span> <span class="nc">IteratorHint</span><span class="p">(</span><span class="n">CompositeTypeHint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;An Iterator type-hint.</span>
<span class="sd"> Iterator[X] defines a type-hint for an object implementing both &#39;__iter__&#39;</span>
<span class="sd"> and a &#39;next&#39; method which yields objects which are all of the same type. Type</span>
<span class="sd"> checking a type-hint of this type is deferred in order to avoid depleting the</span>
<span class="sd"> underlying lazily generated sequence. See decorators.interleave_type_check for</span>
<span class="sd"> further information.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">class</span> <span class="nc">IteratorTypeConstraint</span><span class="p">(</span><span class="n">TypeConstraint</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">t</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">yielded_type</span> <span class="o">=</span> <span class="n">normalize</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>
<span class="k">def</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">&#39;Iterator[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">yielded_type</span><span class="p">)</span>
<span class="k">def</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">return</span> <span class="p">(</span>
<span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">==</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">yielded_type</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">yielded_type</span><span class="p">)</span>
<span class="k">def</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">yielded_type</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_inner_types</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">yielded_type</span>
<span class="k">def</span> <span class="nf">_consistent_with_check_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sub</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span> <span class="ow">and</span>
<span class="n">is_consistent_with</span><span class="p">(</span><span class="n">sub</span><span class="o">.</span><span class="n">yielded_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">yielded_type</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">type_check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span>
<span class="c1"># Special case for lazy types, we only need to enforce the underlying</span>
<span class="c1"># type. This avoid having to compute the entirety of the generator/iter.</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">check_constraint</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">yielded_type</span><span class="p">,</span> <span class="n">instance</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">except</span> <span class="n">CompositeTypeHintError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> hint type-constraint violated: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="k">except</span> <span class="n">SimpleTypeHintError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> hint type-constraint violated. Expected a iterator of type </span><span class="si">%s</span><span class="s1">. &#39;</span>
<span class="s1">&#39;Instead received a iterator of type </span><span class="si">%s</span><span class="s1">.&#39;</span> <span class="o">%</span>
<span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">yielded_type</span><span class="p">),</span> <span class="n">instance</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_param</span><span class="p">):</span>
<span class="n">validate_composite_type_param</span><span class="p">(</span>
<span class="n">type_param</span><span class="p">,</span> <span class="n">error_msg_prefix</span><span class="o">=</span><span class="s1">&#39;Parameter to an Iterator hint&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">IteratorTypeConstraint</span><span class="p">(</span><span class="n">type_param</span><span class="p">)</span>
<span class="n">IteratorTypeConstraint</span> <span class="o">=</span> <span class="n">IteratorHint</span><span class="o">.</span><span class="n">IteratorTypeConstraint</span>
<span class="k">class</span> <span class="nc">WindowedTypeConstraint</span><span class="p">(</span><span class="n">TypeConstraint</span><span class="p">,</span> <span class="n">metaclass</span><span class="o">=</span><span class="n">GetitemConstructor</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;A type constraint for WindowedValue objects.</span>
<span class="sd"> Mostly for internal use.</span>
<span class="sd"> Attributes:</span>
<span class="sd"> inner_type: The type which the element should be an instance of.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inner_type</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span> <span class="o">=</span> <span class="n">normalize</span><span class="p">(</span><span class="n">inner_type</span><span class="p">)</span>
<span class="k">def</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">return</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">WindowedTypeConstraint</span><span class="p">)</span> <span class="ow">and</span>
<span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">inner_type</span><span class="p">)</span>
<span class="k">def</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">inner_type</span><span class="p">)</span> <span class="o">^</span> <span class="mi">13</span> <span class="o">*</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_inner_types</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span>
<span class="k">def</span> <span class="nf">_consistent_with_check_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sub</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span> <span class="ow">and</span>
<span class="n">is_consistent_with</span><span class="p">(</span><span class="n">sub</span><span class="o">.</span><span class="n">inner_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">type_check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span>
<span class="kn">from</span> <span class="nn">apache_beam.transforms</span> <span class="kn">import</span> <span class="n">window</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="n">window</span><span class="o">.</span><span class="n">WindowedValue</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s2">&quot;Window type-constraint violated. Valid object instance &quot;</span>
<span class="s2">&quot;must be of type &#39;WindowedValue&#39;. Instead, an instance of &#39;</span><span class="si">%s</span><span class="s2">&#39; &quot;</span>
<span class="s2">&quot;was received.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">instance</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">check_constraint</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">,</span> <span class="n">instance</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="n">CompositeTypeHintError</span><span class="p">,</span> <span class="n">SimpleTypeHintError</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">CompositeTypeHintError</span><span class="p">(</span>
<span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> hint type-constraint violated. The type of element in &#39;</span>
<span class="s1">&#39;is incorrect. Expected an instance of type </span><span class="si">%s</span><span class="s1">, &#39;</span>
<span class="s1">&#39;instead received an instance of type </span><span class="si">%s</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span>
<span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span>
<span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inner_type</span><span class="p">),</span>
<span class="n">instance</span><span class="o">.</span><span class="n">value</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
<span class="k">class</span> <span class="nc">GeneratorHint</span><span class="p">(</span><span class="n">IteratorHint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;A Generator type hint.</span>
<span class="sd"> Subscriptor is in the form [yield_type, send_type, return_type], however</span>
<span class="sd"> only yield_type is supported. The 2 others are expected to be None.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">type_params</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">type_params</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">type_params</span><span class="p">)</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
<span class="n">yield_type</span><span class="p">,</span> <span class="n">send_type</span><span class="p">,</span> <span class="n">return_type</span> <span class="o">=</span> <span class="n">type_params</span>
<span class="k">if</span> <span class="n">send_type</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">type</span><span class="p">(</span><span class="kc">None</span><span class="p">):</span>
<span class="n">_LOGGER</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s1">&#39;Ignoring send_type hint: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">send_type</span><span class="p">)</span>
<span class="k">if</span> <span class="n">return_type</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">type</span><span class="p">(</span><span class="kc">None</span><span class="p">):</span>
<span class="n">_LOGGER</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s1">&#39;Ignoring return_type hint: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">return_type</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">yield_type</span> <span class="o">=</span> <span class="n">type_params</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">IteratorTypeConstraint</span><span class="p">(</span><span class="n">yield_type</span><span class="p">)</span>
<span class="c1"># Create the actual instances for all defined type-hints above.</span>
<span class="n">Any</span> <span class="o">=</span> <span class="n">AnyTypeConstraint</span><span class="p">()</span>
<span class="n">Union</span> <span class="o">=</span> <span class="n">UnionHint</span><span class="p">()</span>
<span class="n">Optional</span> <span class="o">=</span> <span class="n">OptionalHint</span><span class="p">()</span>
<span class="n">Tuple</span> <span class="o">=</span> <span class="n">TupleHint</span><span class="p">()</span>
<span class="n">List</span> <span class="o">=</span> <span class="n">ListHint</span><span class="p">()</span>
<span class="n">KV</span> <span class="o">=</span> <span class="n">KVHint</span><span class="p">()</span>
<span class="n">Dict</span> <span class="o">=</span> <span class="n">DictHint</span><span class="p">()</span>
<span class="n">Set</span> <span class="o">=</span> <span class="n">SetHint</span><span class="p">()</span>
<span class="n">FrozenSet</span> <span class="o">=</span> <span class="n">FrozenSetHint</span><span class="p">()</span>
<span class="n">Iterable</span> <span class="o">=</span> <span class="n">IterableHint</span><span class="p">()</span>
<span class="n">Iterator</span> <span class="o">=</span> <span class="n">IteratorHint</span><span class="p">()</span>
<span class="n">Generator</span> <span class="o">=</span> <span class="n">GeneratorHint</span><span class="p">()</span>
<span class="n">WindowedValue</span> <span class="o">=</span> <span class="n">WindowedTypeConstraint</span>
<span class="c1"># There is a circular dependency between defining this mapping</span>
<span class="c1"># and using it in normalize(). Initialize it here and populate</span>
<span class="c1"># it below.</span>
<span class="n">_KNOWN_PRIMITIVE_TYPES</span> <span class="o">=</span> <span class="p">{}</span> <span class="c1"># type: typing.Dict[type, typing.Any]</span>
<span class="k">def</span> <span class="nf">normalize</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">none_as_type</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="c1"># None is inconsistantly used for Any, unknown, or NoneType.</span>
<span class="c1"># Avoid circular imports</span>
<span class="kn">from</span> <span class="nn">apache_beam.typehints</span> <span class="kn">import</span> <span class="n">native_type_compatibility</span>
<span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">9</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">x</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="n">x</span> <span class="o">=</span> <span class="n">native_type_compatibility</span><span class="o">.</span><span class="n">convert_builtin_to_typing</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="k">if</span> <span class="n">none_as_type</span> <span class="ow">and</span> <span class="n">x</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">elif</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">_KNOWN_PRIMITIVE_TYPES</span><span class="p">:</span>
<span class="k">return</span> <span class="n">_KNOWN_PRIMITIVE_TYPES</span><span class="p">[</span><span class="n">x</span><span class="p">]</span>
<span class="k">elif</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="s1">&#39;__module__&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="o">==</span> <span class="s1">&#39;typing&#39;</span><span class="p">:</span>
<span class="n">beam_type</span> <span class="o">=</span> <span class="n">native_type_compatibility</span><span class="o">.</span><span class="n">convert_to_beam_type</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="k">if</span> <span class="n">beam_type</span> <span class="o">!=</span> <span class="n">x</span><span class="p">:</span>
<span class="c1"># We were able to do the conversion.</span>
<span class="k">return</span> <span class="n">beam_type</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># It might be a compatible type we don&#39;t understand.</span>
<span class="k">return</span> <span class="n">Any</span>
<span class="k">return</span> <span class="n">x</span>
<span class="n">_KNOWN_PRIMITIVE_TYPES</span><span class="o">.</span><span class="n">update</span><span class="p">({</span>
<span class="nb">dict</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Any</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span>
<span class="nb">list</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Any</span><span class="p">],</span>
<span class="nb">tuple</span><span class="p">:</span> <span class="n">Tuple</span><span class="p">[</span><span class="n">Any</span><span class="p">,</span> <span class="o">...</span><span class="p">],</span>
<span class="nb">set</span><span class="p">:</span> <span class="n">Set</span><span class="p">[</span><span class="n">Any</span><span class="p">],</span>
<span class="nb">frozenset</span><span class="p">:</span> <span class="n">FrozenSet</span><span class="p">[</span><span class="n">Any</span><span class="p">],</span>
<span class="p">})</span>
<span class="k">def</span> <span class="nf">is_consistent_with</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="n">base</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Checks whether sub a is consistent with base.</span>
<span class="sd"> This is according to the terminology of PEP 483/484. This relationship is</span>
<span class="sd"> neither symmetric nor transitive, but a good mnemonic to keep in mind is that</span>
<span class="sd"> is_consistent_with(a, b) is roughly equivalent to the issubclass(a, b)</span>
<span class="sd"> relation, but also handles the special Any type as well as type</span>
<span class="sd"> parameterization.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">sub</span> <span class="o">==</span> <span class="n">base</span><span class="p">:</span>
<span class="c1"># Common special case.</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="n">AnyTypeConstraint</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">AnyTypeConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="n">sub</span> <span class="o">=</span> <span class="n">normalize</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="n">none_as_type</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">base</span> <span class="o">=</span> <span class="n">normalize</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">none_as_type</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="n">UnionConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span><span class="n">is_consistent_with</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">base</span><span class="p">)</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">sub</span><span class="o">.</span><span class="n">union_types</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">TypeConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="n">base</span><span class="o">.</span><span class="n">_consistent_with_check_</span><span class="p">(</span><span class="n">sub</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="n">TypeConstraint</span><span class="p">):</span>
<span class="c1"># Nothing but object lives above any type constraints.</span>
<span class="k">return</span> <span class="n">base</span> <span class="o">==</span> <span class="nb">object</span>
<span class="k">return</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="n">base</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get_yielded_type</span><span class="p">(</span><span class="n">type_hint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Obtains the type of elements yielded by an iterable.</span>
<span class="sd"> Note that &quot;iterable&quot; here means: can be iterated over in a for loop, excluding</span>
<span class="sd"> strings and dicts.</span>
<span class="sd"> Args:</span>
<span class="sd"> type_hint: (TypeConstraint) The iterable in question. Must be normalize()-d.</span>
<span class="sd"> Returns:</span>
<span class="sd"> Yielded type of the iterable.</span>
<span class="sd"> Raises:</span>
<span class="sd"> ValueError if not iterable.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">type_hint</span><span class="p">,</span> <span class="n">AnyTypeConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="n">type_hint</span>
<span class="k">if</span> <span class="n">is_consistent_with</span><span class="p">(</span><span class="n">type_hint</span><span class="p">,</span> <span class="n">Iterator</span><span class="p">[</span><span class="n">Any</span><span class="p">]):</span>
<span class="k">return</span> <span class="n">type_hint</span><span class="o">.</span><span class="n">yielded_type</span>
<span class="k">if</span> <span class="n">is_consistent_with</span><span class="p">(</span><span class="n">type_hint</span><span class="p">,</span> <span class="n">Tuple</span><span class="p">[</span><span class="n">Any</span><span class="p">,</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">type_hint</span><span class="p">,</span> <span class="n">TupleConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="n">Union</span><span class="p">[</span><span class="n">type_hint</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span> <span class="c1"># TupleSequenceConstraint</span>
<span class="k">return</span> <span class="n">type_hint</span><span class="o">.</span><span class="n">inner_type</span>
<span class="k">if</span> <span class="n">is_consistent_with</span><span class="p">(</span><span class="n">type_hint</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">[</span><span class="n">Any</span><span class="p">]):</span>
<span class="k">return</span> <span class="n">type_hint</span><span class="o">.</span><span class="n">inner_type</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> is not iterable&#39;</span> <span class="o">%</span> <span class="n">type_hint</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">coerce_to_kv_type</span><span class="p">(</span><span class="n">element_type</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">side_input_producer</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Attempts to coerce element_type to a compatible kv type.</span>
<span class="sd"> Raises an error on failure.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">side_input_producer</span><span class="p">:</span>
<span class="n">consumer</span> <span class="o">=</span> <span class="s1">&#39;side-input of </span><span class="si">%r</span><span class="s1"> (producer: </span><span class="si">%r</span><span class="s1">)&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">label</span><span class="p">,</span> <span class="n">side_input_producer</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">consumer</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%r</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">label</span>
<span class="c1"># If element_type is not specified, then treat it as `Any`.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">element_type</span><span class="p">:</span>
<span class="k">return</span> <span class="n">KV</span><span class="p">[</span><span class="n">Any</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">element_type</span><span class="p">,</span> <span class="n">TupleHint</span><span class="o">.</span><span class="n">TupleConstraint</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">element_type</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
<span class="k">return</span> <span class="n">element_type</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s2">&quot;Tuple input to </span><span class="si">%s</span><span class="s2"> must have two components. &quot;</span>
<span class="s2">&quot;Found </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">consumer</span><span class="p">,</span> <span class="n">element_type</span><span class="p">))</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">element_type</span><span class="p">,</span> <span class="n">AnyTypeConstraint</span><span class="p">):</span>
<span class="c1"># `Any` type needs to be replaced with a KV[Any, Any] to</span>
<span class="c1"># satisfy the KV form.</span>
<span class="k">return</span> <span class="n">KV</span><span class="p">[</span><span class="n">Any</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">element_type</span><span class="p">,</span> <span class="n">UnionConstraint</span><span class="p">):</span>
<span class="n">union_types</span> <span class="o">=</span> <span class="p">[</span><span class="n">coerce_to_kv_type</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">element_type</span><span class="o">.</span><span class="n">union_types</span><span class="p">]</span>
<span class="k">return</span> <span class="n">KV</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="nb">tuple</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">union_types</span><span class="p">)],</span>
<span class="n">Union</span><span class="p">[</span><span class="nb">tuple</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">union_types</span><span class="p">)]]</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># TODO: Possibly handle other valid types.</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s2">&quot;Input to </span><span class="si">%s</span><span class="s2"> must be compatible with KV[Any, Any]. &quot;</span>
<span class="s2">&quot;Found </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">consumer</span><span class="p">,</span> <span class="n">element_type</span><span class="p">))</span>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>