| |
| |
| <!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 — 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> »</li> |
| |
| <li><a href="../../index.html">Module code</a> »</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 "License"); 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 "AS IS" 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">"""Syntax & 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'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 'indexing' a type-parameter into a defined</span> |
| <span class="sd">CompositeTypeHint instance:</span> |
| |
| <span class="sd"> * 'List[int]'.</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 'list'. Composite type-hints can be parameterized by an</span> |
| <span class="sd">inner simple or composite type-hint, using the 'indexing' 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: 'T' 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"> * '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">'type_check' method on each TypeConstraint.</span> |
| |
| <span class="sd">"""</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">'Any'</span><span class="p">,</span> |
| <span class="s1">'Union'</span><span class="p">,</span> |
| <span class="s1">'Optional'</span><span class="p">,</span> |
| <span class="s1">'Tuple'</span><span class="p">,</span> |
| <span class="s1">'List'</span><span class="p">,</span> |
| <span class="s1">'KV'</span><span class="p">,</span> |
| <span class="s1">'Dict'</span><span class="p">,</span> |
| <span class="s1">'Set'</span><span class="p">,</span> |
| <span class="s1">'FrozenSet'</span><span class="p">,</span> |
| <span class="s1">'Iterable'</span><span class="p">,</span> |
| <span class="s1">'Iterator'</span><span class="p">,</span> |
| <span class="s1">'Generator'</span><span class="p">,</span> |
| <span class="s1">'WindowedValue'</span><span class="p">,</span> |
| <span class="s1">'TypeVariable'</span><span class="p">,</span> |
| <span class="p">]</span> |
| |
| <span class="c1"># A set of the built-in Python types we don'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">"""A metaclass that makes Cls[arg] an alias for Cls(arg)."""</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">"""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"> """</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">"""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"> """</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">"""Determines if the type of 'instance' 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'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"> """</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">"""Iterates over the inner types of the composite type."""</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">"""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"> """</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">"""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"> """</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">"""An internal common base-class for all type constraints with indexing.</span> |
| <span class="sd"> E.G. SequenceTypeConstraint + Tuple's of fixed size.</span> |
| <span class="sd"> """</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">"""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."""</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">"""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 '_consistent_with_check_' 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"> """</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">"""Returns the type at the given index."""</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">"</span><span class="si">%s</span><span class="s2"> type-constraint violated. Valid object instance "</span> |
| <span class="s2">"must be of type '</span><span class="si">%s</span><span class="s2">'. Instead, an instance of '</span><span class="si">%s</span><span class="s2">' "</span> |
| <span class="s2">"was received."</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">'</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 '</span> |
| <span class="s1">'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">, '</span> |
| <span class="s1">'instead received an instance of type </span><span class="si">%s</span><span class="s1">.'</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">'</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 '</span> |
| <span class="s1">'the passed </span><span class="si">%s</span><span class="s1"> is incorrect: </span><span class="si">%s</span><span class="s1">'</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">"""The base-class for all created type-hint classes defined below.</span> |
| |
| <span class="sd"> CompositeTypeHint's serve primarily as TypeConstraint factories. They are</span> |
| <span class="sd"> only required to define a single method: '__getitem__' 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"> '__getitem__' 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"> 'type-aliases' by assigning the returned type-hints to a variable.</span> |
| |
| <span class="sd"> * Example: 'Coordinates = List[Tuple[int, int]]'</span> |
| <span class="sd"> """</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">"""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"> """</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">"""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"> """</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">'_GenericAlias'</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">"""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"> """</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">'__module__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="o">!=</span> <span class="s1">'typing'</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">>=</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"><</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">'</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">'</span> |
| <span class="s1">' is an instance of </span><span class="si">%s</span><span class="s1">.'</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">"""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"> 'type_check', all CompositeTypeHint'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 'type_constraint' is a one of the allowed primitive</span> |
| <span class="sd"> Python types and 'object_instance' isn't an instance of this type.</span> |
| <span class="sd"> CompositeTypeHintError: If 'type_constraint' is a TypeConstraint object and</span> |
| <span class="sd"> 'object_instance' does not satisfy its constraint.</span> |
| <span class="sd"> """</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">"bad type: </span><span class="si">%s</span><span class="s2">"</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">"""An Any type-hint.</span> |
| |
| <span class="sd"> Any is intended to be used as a "don't care" when hinting the types of</span> |
| <span class="sd"> function arguments or return types. All other TypeConstraint's are equivalent</span> |
| <span class="sd"> to 'Any', and its 'type_check' method is a no-op.</span> |
| <span class="sd"> """</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">'Any'</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 "other" 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">'use_name_in_eq'</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">'TypeVariable[</span><span class="si">%s</span><span class="s1">]'</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">'*'</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">"""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] -> 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 'union_types' 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"> """</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">'Union[</span><span class="si">%s</span><span class="s1">]'</span> <span class="o">%</span> <span class="p">(</span> |
| <span class="s1">', '</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] > 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's subtypes.</span> |
| <span class="c1"># E.g. Union[A, B, C] > T if T > A or T > B or T > 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">''</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">'</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">, '</span> |
| <span class="s1">'received </span><span class="si">%s</span><span class="s1"> instead.</span><span class="si">%s</span><span class="s1">'</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">'Cannot create Union without a sequence of types.'</span><span class="p">)</span> |
| |
| <span class="c1"># Flatten nested Union'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">'All parameters to a Union hint'</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">"""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"> """</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">'An Option type-hint only accepts a single type '</span> |
| <span class="s1">'parameter.'</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">'Typehint is not of nullable type'</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">"""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 'X' and the second an instance of type 'Y'.</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 'str'.</span> |
| <span class="sd"> """</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">'Tuple[</span><span class="si">%s</span><span class="s1">, ...]'</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] < Tuple[C, ...] iff A < C and B < 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">'Tuple[</span><span class="si">%s</span><span class="s1">]'</span> <span class="o">%</span> <span class="p">(</span><span class="s1">', '</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">"""Returns the type at the given index."""</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">"Tuple type constraint violated. Valid object instance must be of "</span> |
| <span class="s2">"type 'tuple'. Instead, an instance of '</span><span class="si">%s</span><span class="s2">' was received."</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">'Passed object instance is of the proper type, but differs in '</span> |
| <span class="s1">'length from the hinted type. Expected a tuple of length </span><span class="si">%s</span><span class="s1">, '</span> |
| <span class="s1">'received a tuple of length </span><span class="si">%s</span><span class="s1">.'</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">'</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 '</span> |
| <span class="s1">'the passed tuple is incorrect. Expected an instance of '</span> |
| <span class="s1">'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">.'</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">'</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 '</span> |
| <span class="s1">'the passed tuple is incorrect. </span><span class="si">%s</span><span class="s1">'</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">'Ellipsis can only be used to type-hint an arbitrary '</span> |
| <span class="s1">'length tuple of containing a single type: '</span> |
| <span class="s1">'Tuple[A, ...].'</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">'All parameters to a Tuple hint'</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">"""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 'X' can either be a built-in Python type or an</span> |
| <span class="sd"> instance of another TypeConstraint.</span> |
| |
| <span class="sd"> * ['1', '2', '3'] satisfies List[str]</span> |
| <span class="sd"> """</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">'List[</span><span class="si">%s</span><span class="s1">]'</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">'Parameter to List hint'</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">"""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"> """</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">'Parameter to KV type-hint must be a tuple of types: '</span> |
| <span class="s1">'KV[.., ..].'</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">'Length of parameters to a KV type-hint must be exactly 2. Passed '</span> |
| <span class="s1">'parameters: </span><span class="si">%s</span><span class="s1">, have a length of </span><span class="si">%s</span><span class="s1">.'</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">"""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"> """</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">"""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"> """</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">'Dict[</span><span class="si">%s</span><span class="s1">, </span><span class="si">%s</span><span class="s1">]'</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">''</span><span class="p">):</span> |
| <span class="n">incorrect_type</span> <span class="o">=</span> <span class="s1">'values'</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">'keys'</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">'</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 '</span> |
| <span class="s1">'</span><span class="si">%s</span><span class="s1">. Instead: </span><span class="si">%s</span><span class="s1">'</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">'</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 '</span> |
| <span class="s1">'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">.'</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">'Dict type-constraint violated. All passed instances must be of '</span> |
| <span class="s1">'type dict. </span><span class="si">%s</span><span class="s1"> is of type </span><span class="si">%s</span><span class="s1">.'</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">'Parameter to Dict type-hint must be a tuple of types: '</span> |
| <span class="s1">'Dict[.., ..].'</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">'Length of parameters to a Dict type-hint must be exactly 2. Passed '</span> |
| <span class="s1">'parameters: </span><span class="si">%s</span><span class="s1">, have a length of </span><span class="si">%s</span><span class="s1">.'</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">'Key-type parameter to a Dict hint'</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">'Value-type parameter to a Dict hint'</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">"""A Set type-hint.</span> |
| |
| |
| <span class="sd"> Set[X] defines a type-hint for a set of homogeneous types. 'X' may be either a</span> |
| <span class="sd"> built-in Python type or a another nested TypeConstraint.</span> |
| <span class="sd"> """</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">'Set[</span><span class="si">%s</span><span class="s1">]'</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">'Parameter to a Set hint'</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">"""A FrozenSet type-hint.</span> |
| |
| <span class="sd"> FrozenSet[X] defines a type-hint for a set of homogeneous types. 'X' 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"> """</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">'FrozenSet[</span><span class="si">%s</span><span class="s1">]'</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">'Parameter to a FrozenSet hint'</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">"""An Iterable type-hint.</span> |
| |
| <span class="sd"> Iterable[X] defines a type-hint for an object implementing an '__iter__'</span> |
| <span class="sd"> method which yields objects which are all of the same type.</span> |
| <span class="sd"> """</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">'Iterable[</span><span class="si">%s</span><span class="s1">]'</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] < Iterable[C] if A < C and B < 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">'Parameter to an Iterable hint'</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">"""An Iterator type-hint.</span> |
| |
| <span class="sd"> Iterator[X] defines a type-hint for an object implementing both '__iter__'</span> |
| <span class="sd"> and a 'next' 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"> """</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">'Iterator[</span><span class="si">%s</span><span class="s1">]'</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">'</span><span class="si">%s</span><span class="s1"> hint type-constraint violated: </span><span class="si">%s</span><span class="s1">'</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">'</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">. '</span> |
| <span class="s1">'Instead received a iterator of type </span><span class="si">%s</span><span class="s1">.'</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">'Parameter to an Iterator hint'</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">"""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"> """</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">"Window type-constraint violated. Valid object instance "</span> |
| <span class="s2">"must be of type 'WindowedValue'. Instead, an instance of '</span><span class="si">%s</span><span class="s2">' "</span> |
| <span class="s2">"was received."</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">'</span><span class="si">%s</span><span class="s1"> hint type-constraint violated. The type of element in '</span> |
| <span class="s1">'is incorrect. Expected an instance of type </span><span class="si">%s</span><span class="s1">, '</span> |
| <span class="s1">'instead received an instance of type </span><span class="si">%s</span><span class="s1">.'</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">"""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"> """</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">'Ignoring send_type hint: </span><span class="si">%s</span><span class="s1">'</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">'Ignoring return_type hint: </span><span class="si">%s</span><span class="s1">'</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">>=</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">'__module__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="o">==</span> <span class="s1">'typing'</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'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">"""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"> """</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">"""Obtains the type of elements yielded by an iterable.</span> |
| |
| <span class="sd"> Note that "iterable" 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"> """</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">'</span><span class="si">%s</span><span class="s1"> is not iterable'</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">"""Attempts to coerce element_type to a compatible kv type.</span> |
| |
| <span class="sd"> Raises an error on failure.</span> |
| <span class="sd"> """</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">'side-input of </span><span class="si">%r</span><span class="s1"> (producer: </span><span class="si">%r</span><span class="s1">)'</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">'</span><span class="si">%r</span><span class="s1">'</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">"Tuple input to </span><span class="si">%s</span><span class="s2"> must have two components. "</span> |
| <span class="s2">"Found </span><span class="si">%s</span><span class="s2">."</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">"Input to </span><span class="si">%s</span><span class="s2"> must be compatible with KV[Any, Any]. "</span> |
| <span class="s2">"Found </span><span class="si">%s</span><span class="s2">."</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> |
| © 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> |