blob: 0aa418be7156af94fd96289c2bfb65507bff1fa5 [file] [log] [blame]
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>apache_beam.typehints.trivial_inference &mdash; Apache Beam 2.47.0 documentation</title>
<script type="text/javascript" src="../../../_static/js/modernizr.min.js"></script>
<script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/language_data.js"></script>
<script async="async" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/javascript" src="../../../_static/js/theme.js"></script>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../../../index.html" class="icon icon-home"> Apache Beam
</a>
<div class="version">
2.47.0
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.coders.html">apache_beam.coders package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.dataframe.html">apache_beam.dataframe package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.io.html">apache_beam.io package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.metrics.html">apache_beam.metrics package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.ml.html">apache_beam.ml package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.options.html">apache_beam.options package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.portability.html">apache_beam.portability package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.runners.html">apache_beam.runners package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.testing.html">apache_beam.testing package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.transforms.html">apache_beam.transforms package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.typehints.html">apache_beam.typehints package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.utils.html">apache_beam.utils package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.yaml.html">apache_beam.yaml package</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.error.html">apache_beam.error module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.pipeline.html">apache_beam.pipeline module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../apache_beam.pvalue.html">apache_beam.pvalue module</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../../index.html">Apache Beam</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../../index.html">Docs</a> &raquo;</li>
<li><a href="../../index.html">Module code</a> &raquo;</li>
<li>apache_beam.typehints.trivial_inference</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.trivial_inference</h1><div class="highlight"><pre>
<span></span><span class="c1">#</span>
<span class="c1"># Licensed to the Apache Software Foundation (ASF) under one or more</span>
<span class="c1"># contributor license agreements. See the NOTICE file distributed with</span>
<span class="c1"># this work for additional information regarding copyright ownership.</span>
<span class="c1"># The ASF licenses this file to You under the Apache License, Version 2.0</span>
<span class="c1"># (the &quot;License&quot;); you may not use this file except in compliance with</span>
<span class="c1"># the License. You may obtain a copy of the License at</span>
<span class="c1">#</span>
<span class="c1"># http://www.apache.org/licenses/LICENSE-2.0</span>
<span class="c1">#</span>
<span class="c1"># Unless required by applicable law or agreed to in writing, software</span>
<span class="c1"># distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span>
<span class="c1"># WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
<span class="c1"># See the License for the specific language governing permissions and</span>
<span class="c1"># limitations under the License.</span>
<span class="c1">#</span>
<span class="sd">&quot;&quot;&quot;Trivial type inference for simple functions.</span>
<span class="sd">For internal use only; no backwards-compatibility guarantees.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="c1"># pytype: skip-file</span>
<span class="kn">import</span> <span class="nn">builtins</span>
<span class="kn">import</span> <span class="nn">collections</span>
<span class="kn">import</span> <span class="nn">dis</span>
<span class="kn">import</span> <span class="nn">inspect</span>
<span class="kn">import</span> <span class="nn">pprint</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">traceback</span>
<span class="kn">import</span> <span class="nn">types</span>
<span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">reduce</span>
<span class="kn">from</span> <span class="nn">apache_beam</span> <span class="kn">import</span> <span class="n">pvalue</span>
<span class="kn">from</span> <span class="nn">apache_beam.typehints</span> <span class="kn">import</span> <span class="n">Any</span>
<span class="kn">from</span> <span class="nn">apache_beam.typehints</span> <span class="kn">import</span> <span class="n">row_type</span>
<span class="kn">from</span> <span class="nn">apache_beam.typehints</span> <span class="kn">import</span> <span class="n">typehints</span>
<span class="kn">from</span> <span class="nn">apache_beam.utils</span> <span class="kn">import</span> <span class="n">python_callable</span>
<div class="viewcode-block" id="TypeInferenceError"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.TypeInferenceError">[docs]</a><span class="k">class</span> <span class="nc">TypeInferenceError</span><span class="p">(</span><span class="ne">ValueError</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Error to raise when type inference failed.&quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="instance_to_type"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.instance_to_type">[docs]</a><span class="k">def</span> <span class="nf">instance_to_type</span><span class="p">(</span><span class="n">o</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Given a Python object o, return the corresponding type hint.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">t</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">o</span><span class="p">)</span>
<span class="k">if</span> <span class="n">o</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">t</span> <span class="o">==</span> <span class="n">pvalue</span><span class="o">.</span><span class="n">Row</span><span class="p">:</span>
<span class="k">return</span> <span class="n">row_type</span><span class="o">.</span><span class="n">RowTypeConstraint</span><span class="o">.</span><span class="n">from_fields</span><span class="p">([</span>
<span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">instance_to_type</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">o</span><span class="o">.</span><span class="n">as_dict</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="p">])</span>
<span class="k">elif</span> <span class="n">t</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">typehints</span><span class="o">.</span><span class="n">DISALLOWED_PRIMITIVE_TYPES</span><span class="p">:</span>
<span class="c1"># pylint: disable=bad-option-value</span>
<span class="k">if</span> <span class="n">t</span> <span class="o">==</span> <span class="n">BoundMethod</span><span class="p">:</span>
<span class="k">return</span> <span class="n">types</span><span class="o">.</span><span class="n">MethodType</span>
<span class="k">return</span> <span class="n">t</span>
<span class="k">elif</span> <span class="n">t</span> <span class="o">==</span> <span class="nb">tuple</span><span class="p">:</span>
<span class="k">return</span> <span class="n">typehints</span><span class="o">.</span><span class="n">Tuple</span><span class="p">[[</span><span class="n">instance_to_type</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">o</span><span class="p">]]</span>
<span class="k">elif</span> <span class="n">t</span> <span class="o">==</span> <span class="nb">list</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">o</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="n">typehints</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">typehints</span><span class="o">.</span><span class="n">Union</span><span class="p">[[</span>
<span class="n">instance_to_type</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">o</span>
<span class="p">]]]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">typehints</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">typehints</span><span class="o">.</span><span class="n">Any</span><span class="p">]</span>
<span class="k">elif</span> <span class="n">t</span> <span class="o">==</span> <span class="nb">set</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">o</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="n">typehints</span><span class="o">.</span><span class="n">Set</span><span class="p">[</span><span class="n">typehints</span><span class="o">.</span><span class="n">Union</span><span class="p">[[</span>
<span class="n">instance_to_type</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">o</span>
<span class="p">]]]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">typehints</span><span class="o">.</span><span class="n">Set</span><span class="p">[</span><span class="n">typehints</span><span class="o">.</span><span class="n">Any</span><span class="p">]</span>
<span class="k">elif</span> <span class="n">t</span> <span class="o">==</span> <span class="nb">frozenset</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">o</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="n">typehints</span><span class="o">.</span><span class="n">FrozenSet</span><span class="p">[</span><span class="n">typehints</span><span class="o">.</span><span class="n">Union</span><span class="p">[[</span>
<span class="n">instance_to_type</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">o</span>
<span class="p">]]]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">typehints</span><span class="o">.</span><span class="n">FrozenSet</span><span class="p">[</span><span class="n">typehints</span><span class="o">.</span><span class="n">Any</span><span class="p">]</span>
<span class="k">elif</span> <span class="n">t</span> <span class="o">==</span> <span class="nb">dict</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">o</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="n">typehints</span><span class="o">.</span><span class="n">Dict</span><span class="p">[</span>
<span class="n">typehints</span><span class="o">.</span><span class="n">Union</span><span class="p">[[</span><span class="n">instance_to_type</span><span class="p">(</span><span class="n">k</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">o</span><span class="o">.</span><span class="n">items</span><span class="p">()]],</span>
<span class="n">typehints</span><span class="o">.</span><span class="n">Union</span><span class="p">[[</span><span class="n">instance_to_type</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">o</span><span class="o">.</span><span class="n">items</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="n">typehints</span><span class="o">.</span><span class="n">Dict</span><span class="p">[</span><span class="n">typehints</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="n">typehints</span><span class="o">.</span><span class="n">Any</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">TypeInferenceError</span><span class="p">(</span><span class="s1">&#39;Unknown forbidden type: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">t</span><span class="p">)</span></div>
<div class="viewcode-block" id="union_list"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.union_list">[docs]</a><span class="k">def</span> <span class="nf">union_list</span><span class="p">(</span><span class="n">xs</span><span class="p">,</span> <span class="n">ys</span><span class="p">):</span>
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">xs</span><span class="p">)</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">ys</span><span class="p">)</span>
<span class="k">return</span> <span class="p">[</span><span class="n">union</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">xs</span><span class="p">,</span> <span class="n">ys</span><span class="p">)]</span></div>
<div class="viewcode-block" id="Const"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.Const">[docs]</a><span class="k">class</span> <span class="nc">Const</span><span class="p">(</span><span class="nb">object</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">value</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
<span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">instance_to_type</span><span class="p">(</span><span class="n">value</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="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Const</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">value</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">value</span><span class="p">)</span>
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s1">&#39;Const[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="p">)[:</span><span class="mi">100</span><span class="p">]</span>
<div class="viewcode-block" id="Const.unwrap"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.Const.unwrap">[docs]</a> <span class="nd">@staticmethod</span>
<span class="k">def</span> <span class="nf">unwrap</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">Const</span><span class="p">):</span>
<span class="k">return</span> <span class="n">x</span><span class="o">.</span><span class="n">type</span>
<span class="k">return</span> <span class="n">x</span></div>
<div class="viewcode-block" id="Const.unwrap_all"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.Const.unwrap_all">[docs]</a> <span class="nd">@staticmethod</span>
<span class="k">def</span> <span class="nf">unwrap_all</span><span class="p">(</span><span class="n">xs</span><span class="p">):</span>
<span class="k">return</span> <span class="p">[</span><span class="n">Const</span><span class="o">.</span><span class="n">unwrap</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">xs</span><span class="p">]</span></div></div>
<div class="viewcode-block" id="FrameState"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.FrameState">[docs]</a><span class="k">class</span> <span class="nc">FrameState</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Stores the state of the frame at a particular point of execution.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">local_vars</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="p">(),</span> <span class="n">kw_names</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">f</span> <span class="o">=</span> <span class="n">f</span>
<span class="bp">self</span><span class="o">.</span><span class="n">co</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="vm">__code__</span>
<span class="bp">self</span><span class="o">.</span><span class="n">vars</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">local_vars</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stack</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">stack</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">kw_names</span> <span class="o">=</span> <span class="n">kw_names</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">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">FrameState</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="vm">__dict__</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">tuple</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">items</span><span class="p">())))</span>
<div class="viewcode-block" id="FrameState.copy"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.FrameState.copy">[docs]</a> <span class="k">def</span> <span class="nf">copy</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="n">FrameState</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">f</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">kw_names</span><span class="p">)</span></div>
<div class="viewcode-block" id="FrameState.const_type"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.FrameState.const_type">[docs]</a> <span class="k">def</span> <span class="nf">const_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
<span class="k">return</span> <span class="n">Const</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">co</span><span class="o">.</span><span class="n">co_consts</span><span class="p">[</span><span class="n">i</span><span class="p">])</span></div>
<div class="viewcode-block" id="FrameState.get_closure"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.FrameState.get_closure">[docs]</a> <span class="k">def</span> <span class="nf">get_closure</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
<span class="n">num_cellvars</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">co</span><span class="o">.</span><span class="n">co_cellvars</span><span class="p">)</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">num_cellvars</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">f</span><span class="o">.</span><span class="vm">__closure__</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="n">num_cellvars</span><span class="p">]</span><span class="o">.</span><span class="n">cell_contents</span></div>
<div class="viewcode-block" id="FrameState.closure_type"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.FrameState.closure_type">[docs]</a> <span class="k">def</span> <span class="nf">closure_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a TypeConstraint or Const.&quot;&quot;&quot;</span>
<span class="n">val</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_closure</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">typehints</span><span class="o">.</span><span class="n">TypeConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="n">val</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">Const</span><span class="p">(</span><span class="n">val</span><span class="p">)</span></div>
<div class="viewcode-block" id="FrameState.get_global"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.FrameState.get_global">[docs]</a> <span class="k">def</span> <span class="nf">get_global</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
<span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_name</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">f</span><span class="o">.</span><span class="vm">__globals__</span><span class="p">:</span>
<span class="k">return</span> <span class="n">Const</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">f</span><span class="o">.</span><span class="vm">__globals__</span><span class="p">[</span><span class="n">name</span><span class="p">])</span>
<span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">builtins</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span>
<span class="k">return</span> <span class="n">Const</span><span class="p">(</span><span class="n">builtins</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="n">name</span><span class="p">])</span>
<span class="k">return</span> <span class="n">Any</span></div>
<div class="viewcode-block" id="FrameState.get_name"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.FrameState.get_name">[docs]</a> <span class="k">def</span> <span class="nf">get_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">co</span><span class="o">.</span><span class="n">co_names</span><span class="p">[</span><span class="n">i</span><span class="p">]</span></div>
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s1">&#39;Stack: </span><span class="si">%s</span><span class="s1"> Vars: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="p">)</span>
<span class="k">def</span> <span class="fm">__or__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="n">other</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">other</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">return</span> <span class="n">FrameState</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">f</span><span class="p">,</span>
<span class="n">union_list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">vars</span><span class="p">),</span>
<span class="n">union_list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">stack</span><span class="p">))</span>
<span class="k">def</span> <span class="fm">__ror__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">left</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span> <span class="o">|</span> <span class="n">left</span></div>
<div class="viewcode-block" id="union"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.union">[docs]</a><span class="k">def</span> <span class="nf">union</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="w"> </span><span class="sd">&quot;&quot;&quot;Returns the union of two types or Const values.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">a</span> <span class="o">==</span> <span class="n">b</span><span class="p">:</span>
<span class="k">return</span> <span class="n">a</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="n">a</span><span class="p">:</span>
<span class="k">return</span> <span class="n">b</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="n">b</span><span class="p">:</span>
<span class="k">return</span> <span class="n">a</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">Const</span><span class="o">.</span><span class="n">unwrap</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">Const</span><span class="o">.</span><span class="n">unwrap</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
<span class="c1"># TODO(robertwb): Work this into the Union code in a more generic way.</span>
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="o">==</span> <span class="nb">type</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="ow">and</span> <span class="n">element_type</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="o">==</span> <span class="n">typehints</span><span class="o">.</span><span class="n">Union</span><span class="p">[()]:</span>
<span class="k">return</span> <span class="n">b</span>
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="o">==</span> <span class="nb">type</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="ow">and</span> <span class="n">element_type</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="o">==</span> <span class="n">typehints</span><span class="o">.</span><span class="n">Union</span><span class="p">[()]:</span>
<span class="k">return</span> <span class="n">a</span>
<span class="k">return</span> <span class="n">typehints</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">]</span></div>
<div class="viewcode-block" id="finalize_hints"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.finalize_hints">[docs]</a><span class="k">def</span> <span class="nf">finalize_hints</span><span class="p">(</span><span class="n">type_hint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Sets type hint for empty data structures to Any.&quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">visitor</span><span class="p">(</span><span class="n">tc</span><span class="p">,</span> <span class="n">unused_arg</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">tc</span><span class="p">,</span> <span class="n">typehints</span><span class="o">.</span><span class="n">DictConstraint</span><span class="p">):</span>
<span class="n">empty_union</span> <span class="o">=</span> <span class="n">typehints</span><span class="o">.</span><span class="n">Union</span><span class="p">[()]</span>
<span class="k">if</span> <span class="n">tc</span><span class="o">.</span><span class="n">key_type</span> <span class="o">==</span> <span class="n">empty_union</span><span class="p">:</span>
<span class="n">tc</span><span class="o">.</span><span class="n">key_type</span> <span class="o">=</span> <span class="n">Any</span>
<span class="k">if</span> <span class="n">tc</span><span class="o">.</span><span class="n">value_type</span> <span class="o">==</span> <span class="n">empty_union</span><span class="p">:</span>
<span class="n">tc</span><span class="o">.</span><span class="n">value_type</span> <span class="o">=</span> <span class="n">Any</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">typehints</span><span class="o">.</span><span class="n">TypeConstraint</span><span class="p">):</span>
<span class="n">type_hint</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="kc">None</span><span class="p">)</span></div>
<div class="viewcode-block" id="element_type"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.element_type">[docs]</a><span class="k">def</span> <span class="nf">element_type</span><span class="p">(</span><span class="n">hint</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns the element type of a composite type.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">hint</span> <span class="o">=</span> <span class="n">Const</span><span class="o">.</span><span class="n">unwrap</span><span class="p">(</span><span class="n">hint</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">hint</span><span class="p">,</span> <span class="n">typehints</span><span class="o">.</span><span class="n">SequenceTypeConstraint</span><span class="p">):</span>
<span class="k">return</span> <span class="n">hint</span><span class="o">.</span><span class="n">inner_type</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">hint</span><span class="p">,</span> <span class="n">typehints</span><span class="o">.</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">typehints</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">hint</span><span class="o">.</span><span class="n">tuple_types</span><span class="p">]</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">hint</span><span class="p">,</span>
<span class="n">typehints</span><span class="o">.</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="ow">not</span> <span class="n">hint</span><span class="o">.</span><span class="n">union_types</span><span class="p">:</span>
<span class="k">return</span> <span class="n">hint</span>
<span class="k">return</span> <span class="n">Any</span></div>
<div class="viewcode-block" id="key_value_types"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.key_value_types">[docs]</a><span class="k">def</span> <span class="nf">key_value_types</span><span class="p">(</span><span class="n">kv_type</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns the key and value type of a KV type.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># TODO(robertwb): Unions of tuples, etc.</span>
<span class="c1"># TODO(robertwb): Assert?</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">kv_type</span><span class="p">,</span> <span class="n">typehints</span><span class="o">.</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="nb">len</span><span class="p">(</span><span class="n">kv_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">kv_type</span><span class="o">.</span><span class="n">tuple_types</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span>
<span class="n">kv_type</span><span class="p">,</span> <span class="n">typehints</span><span class="o">.</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="ow">not</span> <span class="n">kv_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_type</span><span class="p">,</span> <span class="n">kv_type</span>
<span class="k">return</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Any</span></div>
<span class="n">known_return_types</span> <span class="o">=</span> <span class="p">{</span>
<span class="nb">len</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<span class="nb">hash</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<span class="p">}</span>
<div class="viewcode-block" id="BoundMethod"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.BoundMethod">[docs]</a><span class="k">class</span> <span class="nc">BoundMethod</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Used to create a bound method when we only know the type of the instance.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Instantiates a bound method object.</span>
<span class="sd"> Args:</span>
<span class="sd"> func (types.FunctionType): The method&#39;s underlying function</span>
<span class="sd"> type (type): The class of the method.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">func</span> <span class="o">=</span> <span class="n">func</span>
<span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="nb">type</span></div>
<div class="viewcode-block" id="hashable"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.hashable">[docs]</a><span class="k">def</span> <span class="nf">hashable</span><span class="p">(</span><span class="n">c</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="nb">hash</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="infer_return_type"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.infer_return_type">[docs]</a><span class="k">def</span> <span class="nf">infer_return_type</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">input_types</span><span class="p">,</span> <span class="n">debug</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="mi">5</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Analyses a callable to deduce its return type.</span>
<span class="sd"> Args:</span>
<span class="sd"> c: A Python callable to infer the return type of.</span>
<span class="sd"> input_types: A sequence of inputs corresponding to the input types.</span>
<span class="sd"> debug: Whether to print verbose debugging information.</span>
<span class="sd"> depth: Maximum inspection depth during type inference.</span>
<span class="sd"> Returns:</span>
<span class="sd"> A TypeConstraint that that the return value of this function will (likely)</span>
<span class="sd"> satisfy given the specified inputs.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">hashable</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="ow">and</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">known_return_types</span><span class="p">:</span>
<span class="k">return</span> <span class="n">known_return_types</span><span class="p">[</span><span class="n">c</span><span class="p">]</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">FunctionType</span><span class="p">):</span>
<span class="k">return</span> <span class="n">infer_return_type_func</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">input_types</span><span class="p">,</span> <span class="n">debug</span><span class="p">,</span> <span class="n">depth</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">MethodType</span><span class="p">):</span>
<span class="k">if</span> <span class="n">c</span><span class="o">.</span><span class="vm">__self__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">input_types</span> <span class="o">=</span> <span class="p">[</span><span class="n">Const</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="vm">__self__</span><span class="p">)]</span> <span class="o">+</span> <span class="n">input_types</span>
<span class="k">return</span> <span class="n">infer_return_type_func</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="vm">__func__</span><span class="p">,</span> <span class="n">input_types</span><span class="p">,</span> <span class="n">debug</span><span class="p">,</span> <span class="n">depth</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">BoundMethod</span><span class="p">):</span>
<span class="n">input_types</span> <span class="o">=</span> <span class="p">[</span><span class="n">c</span><span class="o">.</span><span class="n">type</span><span class="p">]</span> <span class="o">+</span> <span class="n">input_types</span>
<span class="k">return</span> <span class="n">infer_return_type_func</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">func</span><span class="p">,</span> <span class="n">input_types</span><span class="p">,</span> <span class="n">debug</span><span class="p">,</span> <span class="n">depth</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">inspect</span><span class="o">.</span><span class="n">isclass</span><span class="p">(</span><span class="n">c</span><span class="p">):</span>
<span class="k">if</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">typehints</span><span class="o">.</span><span class="n">DISALLOWED_PRIMITIVE_TYPES</span><span class="p">:</span>
<span class="k">return</span> <span class="p">{</span>
<span class="nb">list</span><span class="p">:</span> <span class="n">typehints</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">Any</span><span class="p">],</span>
<span class="nb">set</span><span class="p">:</span> <span class="n">typehints</span><span class="o">.</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">typehints</span><span class="o">.</span><span class="n">FrozenSet</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">typehints</span><span class="o">.</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">dict</span><span class="p">:</span> <span class="n">typehints</span><span class="o">.</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="p">}[</span><span class="n">c</span><span class="p">]</span>
<span class="k">return</span> <span class="n">c</span>
<span class="k">elif</span> <span class="p">(</span><span class="n">c</span> <span class="o">==</span> <span class="nb">getattr</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">input_types</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span> <span class="ow">and</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">input_types</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">Const</span><span class="p">)):</span>
<span class="kn">from</span> <span class="nn">apache_beam.typehints</span> <span class="kn">import</span> <span class="n">opcodes</span>
<span class="k">return</span> <span class="n">opcodes</span><span class="o">.</span><span class="n">_getattr</span><span class="p">(</span><span class="n">input_types</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">input_types</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">python_callable</span><span class="o">.</span><span class="n">PythonCallableWithSource</span><span class="p">):</span>
<span class="c1"># TODO(BEAM-24755): This can be removed once support for</span>
<span class="c1"># inference across *args and **kwargs is implemented.</span>
<span class="k">return</span> <span class="n">infer_return_type</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">_callable</span><span class="p">,</span> <span class="n">input_types</span><span class="p">,</span> <span class="n">debug</span><span class="p">,</span> <span class="n">depth</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">Any</span>
<span class="k">except</span> <span class="n">TypeInferenceError</span><span class="p">:</span>
<span class="k">if</span> <span class="n">debug</span><span class="p">:</span>
<span class="n">traceback</span><span class="o">.</span><span class="n">print_exc</span><span class="p">()</span>
<span class="k">return</span> <span class="n">Any</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="k">if</span> <span class="n">debug</span><span class="p">:</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
<span class="k">raise</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">Any</span></div>
<div class="viewcode-block" id="infer_return_type_func"><a class="viewcode-back" href="../../../apache_beam.typehints.trivial_inference.html#apache_beam.typehints.trivial_inference.infer_return_type_func">[docs]</a><span class="k">def</span> <span class="nf">infer_return_type_func</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">input_types</span><span class="p">,</span> <span class="n">debug</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Analyses a function to deduce its return type.</span>
<span class="sd"> Args:</span>
<span class="sd"> f: A Python function object to infer the return type of.</span>
<span class="sd"> input_types: A sequence of inputs corresponding to the input types.</span>
<span class="sd"> debug: Whether to print verbose debugging information.</span>
<span class="sd"> depth: Maximum inspection depth during type inference.</span>
<span class="sd"> Returns:</span>
<span class="sd"> A TypeConstraint that that the return value of this function will (likely)</span>
<span class="sd"> satisfy given the specified inputs.</span>
<span class="sd"> Raises:</span>
<span class="sd"> TypeInferenceError: if no type can be inferred.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">debug</span><span class="p">:</span>
<span class="nb">print</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">id</span><span class="p">(</span><span class="n">f</span><span class="p">),</span> <span class="n">input_types</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</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="p">,</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="p">)</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">11</span><span class="p">):</span>
<span class="n">dis</span><span class="o">.</span><span class="n">dis</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">show_caches</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">dis</span><span class="o">.</span><span class="n">dis</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">opcodes</span>
<span class="n">simple_ops</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">((</span><span class="n">k</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">v</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">opcodes</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
<span class="n">co</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="vm">__code__</span>
<span class="n">code</span> <span class="o">=</span> <span class="n">co</span><span class="o">.</span><span class="n">co_code</span>
<span class="n">end</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
<span class="n">pc</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">free</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">yields</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="n">returns</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="c1"># TODO(robertwb): Default args via inspect module.</span>
<span class="n">local_vars</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">input_types</span><span class="p">)</span> <span class="o">+</span> <span class="p">[</span><span class="n">typehints</span><span class="o">.</span><span class="n">Union</span><span class="p">[()]]</span> <span class="o">*</span> <span class="p">(</span>
<span class="nb">len</span><span class="p">(</span><span class="n">co</span><span class="o">.</span><span class="n">co_varnames</span><span class="p">)</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">input_types</span><span class="p">))</span>
<span class="n">state</span> <span class="o">=</span> <span class="n">FrameState</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">local_vars</span><span class="p">)</span>
<span class="n">states</span> <span class="o">=</span> <span class="n">collections</span><span class="o">.</span><span class="n">defaultdict</span><span class="p">(</span><span class="k">lambda</span><span class="p">:</span> <span class="kc">None</span><span class="p">)</span>
<span class="n">jumps</span> <span class="o">=</span> <span class="n">collections</span><span class="o">.</span><span class="n">defaultdict</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span>
<span class="c1"># In Python 3, use dis library functions to disassemble bytecode and handle</span>
<span class="c1"># EXTENDED_ARGs.</span>
<span class="n">ofs_table</span> <span class="o">=</span> <span class="p">{}</span> <span class="c1"># offset -&gt; instruction</span>
<span class="k">if</span> <span class="p">(</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="p">,</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="p">)</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">11</span><span class="p">):</span>
<span class="n">dis_ints</span> <span class="o">=</span> <span class="n">dis</span><span class="o">.</span><span class="n">get_instructions</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">show_caches</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">dis_ints</span> <span class="o">=</span> <span class="n">dis</span><span class="o">.</span><span class="n">get_instructions</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="k">for</span> <span class="n">instruction</span> <span class="ow">in</span> <span class="n">dis_ints</span><span class="p">:</span>
<span class="n">ofs_table</span><span class="p">[</span><span class="n">instruction</span><span class="o">.</span><span class="n">offset</span><span class="p">]</span> <span class="o">=</span> <span class="n">instruction</span>
<span class="c1"># Python 3.6+: 1 byte opcode + 1 byte arg (2 bytes, arg may be ignored).</span>
<span class="n">inst_size</span> <span class="o">=</span> <span class="mi">2</span>
<span class="n">opt_arg_size</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1"># Python 3.10: bpo-27129 changes jump offsets to use instruction offsets,</span>
<span class="c1"># not byte offsets. The offsets were halved (16 bits fro instructions vs 8</span>
<span class="c1"># bits for bytes), so we have to double the value of arg.</span>
<span class="k">if</span> <span class="p">(</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="p">,</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="p">)</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">10</span><span class="p">):</span>
<span class="n">jump_multiplier</span> <span class="o">=</span> <span class="mi">2</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">jump_multiplier</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">last_pc</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">while</span> <span class="n">pc</span> <span class="o">&lt;</span> <span class="n">end</span><span class="p">:</span> <span class="c1"># pylint: disable=too-many-nested-blocks</span>
<span class="n">start</span> <span class="o">=</span> <span class="n">pc</span>
<span class="n">instruction</span> <span class="o">=</span> <span class="n">ofs_table</span><span class="p">[</span><span class="n">pc</span><span class="p">]</span>
<span class="n">op</span> <span class="o">=</span> <span class="n">instruction</span><span class="o">.</span><span class="n">opcode</span>
<span class="k">if</span> <span class="n">debug</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;--&gt;&#39;</span> <span class="k">if</span> <span class="n">pc</span> <span class="o">==</span> <span class="n">last_pc</span> <span class="k">else</span> <span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="n">pc</span><span class="p">)</span><span class="o">.</span><span class="n">rjust</span><span class="p">(</span><span class="mi">4</span><span class="p">),</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">dis</span><span class="o">.</span><span class="n">opname</span><span class="p">[</span><span class="n">op</span><span class="p">]</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">20</span><span class="p">),</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="n">pc</span> <span class="o">+=</span> <span class="n">inst_size</span>
<span class="n">arg</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">op</span> <span class="o">&gt;=</span> <span class="n">dis</span><span class="o">.</span><span class="n">HAVE_ARGUMENT</span><span class="p">:</span>
<span class="n">arg</span> <span class="o">=</span> <span class="n">instruction</span><span class="o">.</span><span class="n">arg</span>
<span class="n">pc</span> <span class="o">+=</span> <span class="n">opt_arg_size</span>
<span class="k">if</span> <span class="n">debug</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span><span class="o">.</span><span class="n">rjust</span><span class="p">(</span><span class="mi">5</span><span class="p">),</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">op</span> <span class="ow">in</span> <span class="n">dis</span><span class="o">.</span><span class="n">hasconst</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;(&#39;</span> <span class="o">+</span> <span class="nb">repr</span><span class="p">(</span><span class="n">co</span><span class="o">.</span><span class="n">co_consts</span><span class="p">[</span><span class="n">arg</span><span class="p">])</span> <span class="o">+</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">op</span> <span class="ow">in</span> <span class="n">dis</span><span class="o">.</span><span class="n">hasname</span><span class="p">:</span>
<span class="k">if</span> <span class="p">(</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="p">,</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="p">)</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">11</span><span class="p">):</span>
<span class="c1"># Pre-emptively bit-shift so the print doesn&#39;t go out of index</span>
<span class="n">print_arg</span> <span class="o">=</span> <span class="n">arg</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">print_arg</span> <span class="o">=</span> <span class="n">arg</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;(&#39;</span> <span class="o">+</span> <span class="n">co</span><span class="o">.</span><span class="n">co_names</span><span class="p">[</span><span class="n">print_arg</span><span class="p">]</span> <span class="o">+</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">op</span> <span class="ow">in</span> <span class="n">dis</span><span class="o">.</span><span class="n">hasjrel</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;(to &#39;</span> <span class="o">+</span> <span class="nb">repr</span><span class="p">(</span><span class="n">pc</span> <span class="o">+</span> <span class="p">(</span><span class="n">arg</span> <span class="o">*</span> <span class="n">jump_multiplier</span><span class="p">))</span> <span class="o">+</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">op</span> <span class="ow">in</span> <span class="n">dis</span><span class="o">.</span><span class="n">haslocal</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;(&#39;</span> <span class="o">+</span> <span class="n">co</span><span class="o">.</span><span class="n">co_varnames</span><span class="p">[</span><span class="n">arg</span><span class="p">]</span> <span class="o">+</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">op</span> <span class="ow">in</span> <span class="n">dis</span><span class="o">.</span><span class="n">hascompare</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;(&#39;</span> <span class="o">+</span> <span class="n">dis</span><span class="o">.</span><span class="n">cmp_op</span><span class="p">[</span><span class="n">arg</span><span class="p">]</span> <span class="o">+</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">op</span> <span class="ow">in</span> <span class="n">dis</span><span class="o">.</span><span class="n">hasfree</span><span class="p">:</span>
<span class="k">if</span> <span class="n">free</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">free</span> <span class="o">=</span> <span class="n">co</span><span class="o">.</span><span class="n">co_cellvars</span> <span class="o">+</span> <span class="n">co</span><span class="o">.</span><span class="n">co_freevars</span>
<span class="c1"># From 3.11 on the arg is no longer offset by len(co_varnames)</span>
<span class="c1"># so we adjust it back</span>
<span class="n">print_arg</span> <span class="o">=</span> <span class="n">arg</span>
<span class="k">if</span> <span class="p">(</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="p">,</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="p">)</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">11</span><span class="p">):</span>
<span class="n">print_arg</span> <span class="o">=</span> <span class="n">arg</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">co</span><span class="o">.</span><span class="n">co_varnames</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;(&#39;</span> <span class="o">+</span> <span class="n">free</span><span class="p">[</span><span class="n">print_arg</span><span class="p">]</span> <span class="o">+</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="c1"># Actually emulate the op.</span>
<span class="k">if</span> <span class="n">state</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">states</span><span class="p">[</span><span class="n">start</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="c1"># No control reaches here (yet).</span>
<span class="k">if</span> <span class="n">debug</span><span class="p">:</span>
<span class="nb">print</span><span class="p">()</span>
<span class="k">continue</span>
<span class="n">state</span> <span class="o">|=</span> <span class="n">states</span><span class="p">[</span><span class="n">start</span><span class="p">]</span>
<span class="n">opname</span> <span class="o">=</span> <span class="n">dis</span><span class="o">.</span><span class="n">opname</span><span class="p">[</span><span class="n">op</span><span class="p">]</span>
<span class="n">jmp</span> <span class="o">=</span> <span class="n">jmp_state</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">opname</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;CALL_FUNCTION&#39;</span><span class="p">):</span>
<span class="k">if</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;CALL_FUNCTION&#39;</span><span class="p">:</span>
<span class="n">pop_count</span> <span class="o">=</span> <span class="n">arg</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">depth</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">Any</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">],</span> <span class="n">Const</span><span class="p">):</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">infer_return_type</span><span class="p">(</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">]</span><span class="o">.</span><span class="n">value</span><span class="p">,</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="mi">1</span> <span class="o">-</span> <span class="n">pop_count</span><span class="p">:],</span>
<span class="n">debug</span><span class="o">=</span><span class="n">debug</span><span class="p">,</span>
<span class="n">depth</span><span class="o">=</span><span class="n">depth</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">Any</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;CALL_FUNCTION_KW&#39;</span><span class="p">:</span>
<span class="c1"># TODO(BEAM-24755): Handle keyword arguments. Requires passing them by</span>
<span class="c1"># name to infer_return_type.</span>
<span class="n">pop_count</span> <span class="o">=</span> <span class="n">arg</span> <span class="o">+</span> <span class="mi">2</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">],</span> <span class="n">Const</span><span class="p">):</span>
<span class="kn">from</span> <span class="nn">apache_beam.pvalue</span> <span class="kn">import</span> <span class="n">Row</span>
<span class="k">if</span> <span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">]</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="n">Row</span><span class="p">:</span>
<span class="n">fields</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">value</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">row_type</span><span class="o">.</span><span class="n">RowTypeConstraint</span><span class="o">.</span><span class="n">from_fields</span><span class="p">(</span>
<span class="nb">list</span><span class="p">(</span>
<span class="nb">zip</span><span class="p">(</span>
<span class="n">fields</span><span class="p">,</span>
<span class="n">Const</span><span class="o">.</span><span class="n">unwrap_all</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span> <span class="o">+</span> <span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]))))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">Any</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">Any</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;CALL_FUNCTION_EX&#39;</span><span class="p">:</span>
<span class="c1"># stack[-has_kwargs]: Map of keyword args.</span>
<span class="c1"># stack[-1 - has_kwargs]: Iterable of positional args.</span>
<span class="c1"># stack[-2 - has_kwargs]: Function to call.</span>
<span class="n">has_kwargs</span> <span class="o">=</span> <span class="n">arg</span> <span class="o">&amp;</span> <span class="mi">1</span> <span class="c1"># type: int</span>
<span class="n">pop_count</span> <span class="o">=</span> <span class="n">has_kwargs</span> <span class="o">+</span> <span class="mi">2</span>
<span class="k">if</span> <span class="n">has_kwargs</span><span class="p">:</span>
<span class="c1"># TODO(BEAM-24755): Unimplemented. Requires same functionality as a</span>
<span class="c1"># CALL_FUNCTION_KW implementation.</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">Any</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">args</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="n">_callable</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">typehints</span><span class="o">.</span><span class="n">ListConstraint</span><span class="p">):</span>
<span class="c1"># Case where there&#39;s a single var_arg argument.</span>
<span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">args</span><span class="p">]</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">typehints</span><span class="o">.</span><span class="n">TupleConstraint</span><span class="p">):</span>
<span class="n">args</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">_inner_types</span><span class="p">())</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">typehints</span><span class="o">.</span><span class="n">SequenceTypeConstraint</span><span class="p">):</span>
<span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">element_type</span><span class="p">(</span><span class="n">args</span><span class="p">)]</span> <span class="o">*</span> <span class="nb">len</span><span class="p">(</span>
<span class="n">inspect</span><span class="o">.</span><span class="n">getfullargspec</span><span class="p">(</span><span class="n">_callable</span><span class="o">.</span><span class="n">value</span><span class="p">)</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">infer_return_type</span><span class="p">(</span>
<span class="n">_callable</span><span class="o">.</span><span class="n">value</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">debug</span><span class="o">=</span><span class="n">debug</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="n">depth</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">TypeInferenceError</span><span class="p">(</span><span class="s1">&#39;unable to handle </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">opname</span><span class="p">)</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">:]</span> <span class="o">=</span> <span class="p">[</span><span class="n">return_type</span><span class="p">]</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;CALL_METHOD&#39;</span><span class="p">:</span>
<span class="n">pop_count</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">arg</span>
<span class="c1"># LOAD_METHOD will return a non-Const (Any) if loading from an Any.</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">],</span> <span class="n">Const</span><span class="p">)</span> <span class="ow">and</span> <span class="n">depth</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">infer_return_type</span><span class="p">(</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">]</span><span class="o">.</span><span class="n">value</span><span class="p">,</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="mi">1</span> <span class="o">-</span> <span class="n">pop_count</span><span class="p">:],</span>
<span class="n">debug</span><span class="o">=</span><span class="n">debug</span><span class="p">,</span>
<span class="n">depth</span><span class="o">=</span><span class="n">depth</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">typehints</span><span class="o">.</span><span class="n">Any</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">:]</span> <span class="o">=</span> <span class="p">[</span><span class="n">return_type</span><span class="p">]</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;CALL&#39;</span><span class="p">:</span>
<span class="n">pop_count</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">arg</span>
<span class="c1"># Keyword Args case</span>
<span class="k">if</span> <span class="n">state</span><span class="o">.</span><span class="n">kw_names</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">],</span> <span class="n">Const</span><span class="p">):</span>
<span class="kn">from</span> <span class="nn">apache_beam.pvalue</span> <span class="kn">import</span> <span class="n">Row</span>
<span class="k">if</span> <span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">]</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="n">Row</span><span class="p">:</span>
<span class="n">fields</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">kw_names</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">row_type</span><span class="o">.</span><span class="n">RowTypeConstraint</span><span class="o">.</span><span class="n">from_fields</span><span class="p">(</span>
<span class="nb">list</span><span class="p">(</span>
<span class="nb">zip</span><span class="p">(</span><span class="n">fields</span><span class="p">,</span>
<span class="n">Const</span><span class="o">.</span><span class="n">unwrap_all</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span> <span class="o">+</span> <span class="mi">1</span><span class="p">:]))))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">Any</span>
<span class="n">state</span><span class="o">.</span><span class="n">kw_names</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># Handle lambdas always having an arg of 0 for CALL</span>
<span class="c1"># See https://github.com/python/cpython/issues/102403 for context.</span>
<span class="k">if</span> <span class="n">pop_count</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">while</span> <span class="n">pop_count</span> <span class="o">&lt;=</span> <span class="nb">len</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">],</span> <span class="n">Const</span><span class="p">):</span>
<span class="k">break</span>
<span class="n">pop_count</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">depth</span> <span class="o">&lt;=</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">pop_count</span> <span class="o">&gt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">):</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">Any</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">],</span> <span class="n">Const</span><span class="p">):</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">infer_return_type</span><span class="p">(</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">]</span><span class="o">.</span><span class="n">value</span><span class="p">,</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="mi">1</span> <span class="o">-</span> <span class="n">pop_count</span><span class="p">:],</span>
<span class="n">debug</span><span class="o">=</span><span class="n">debug</span><span class="p">,</span>
<span class="n">depth</span><span class="o">=</span><span class="n">depth</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">return_type</span> <span class="o">=</span> <span class="n">Any</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="n">pop_count</span><span class="p">:]</span> <span class="o">=</span> <span class="p">[</span><span class="n">return_type</span><span class="p">]</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="ow">in</span> <span class="n">simple_ops</span><span class="p">:</span>
<span class="k">if</span> <span class="n">debug</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Executing simple op &quot;</span> <span class="o">+</span> <span class="n">opname</span><span class="p">)</span>
<span class="n">simple_ops</span><span class="p">[</span><span class="n">opname</span><span class="p">](</span><span class="n">state</span><span class="p">,</span> <span class="n">arg</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;RETURN_VALUE&#39;</span><span class="p">:</span>
<span class="n">returns</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">state</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;YIELD_VALUE&#39;</span><span class="p">:</span>
<span class="n">yields</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;JUMP_FORWARD&#39;</span><span class="p">:</span>
<span class="n">jmp</span> <span class="o">=</span> <span class="n">pc</span> <span class="o">+</span> <span class="n">arg</span> <span class="o">*</span> <span class="n">jump_multiplier</span>
<span class="n">jmp_state</span> <span class="o">=</span> <span class="n">state</span>
<span class="n">state</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;JUMP_BACKWARD&#39;</span><span class="p">,</span> <span class="s1">&#39;JUMP_BACKWARD_NO_INTERRUPT&#39;</span><span class="p">):</span>
<span class="n">jmp</span> <span class="o">=</span> <span class="n">pc</span> <span class="o">-</span> <span class="p">(</span><span class="n">arg</span> <span class="o">*</span> <span class="n">jump_multiplier</span><span class="p">)</span>
<span class="n">jmp_state</span> <span class="o">=</span> <span class="n">state</span>
<span class="n">state</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;JUMP_ABSOLUTE&#39;</span><span class="p">:</span>
<span class="n">jmp</span> <span class="o">=</span> <span class="n">arg</span> <span class="o">*</span> <span class="n">jump_multiplier</span>
<span class="n">jmp_state</span> <span class="o">=</span> <span class="n">state</span>
<span class="n">state</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;POP_JUMP_IF_TRUE&#39;</span><span class="p">,</span> <span class="s1">&#39;POP_JUMP_IF_FALSE&#39;</span><span class="p">):</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="n">jmp</span> <span class="o">=</span> <span class="n">arg</span> <span class="o">*</span> <span class="n">jump_multiplier</span>
<span class="n">jmp_state</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;POP_JUMP_FORWARD_IF_TRUE&#39;</span><span class="p">,</span> <span class="s1">&#39;POP_JUMP_FORWARD_IF_FALSE&#39;</span><span class="p">):</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="n">jmp</span> <span class="o">=</span> <span class="n">pc</span> <span class="o">+</span> <span class="n">arg</span> <span class="o">*</span> <span class="n">jump_multiplier</span>
<span class="n">jmp_state</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;POP_JUMP_BACKWARD_IF_TRUE&#39;</span><span class="p">,</span> <span class="s1">&#39;POP_JUMP_BACKWARD_IF_FALSE&#39;</span><span class="p">):</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="n">jmp</span> <span class="o">=</span> <span class="n">pc</span> <span class="o">-</span> <span class="p">(</span><span class="n">arg</span> <span class="o">*</span> <span class="n">jump_multiplier</span><span class="p">)</span>
<span class="n">jmp_state</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;POP_JUMP_FORWARD_IF_NONE&#39;</span><span class="p">,</span> <span class="s1">&#39;POP_JUMP_FORWARD_IF_NOT_NONE&#39;</span><span class="p">):</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="n">jmp</span> <span class="o">=</span> <span class="n">pc</span> <span class="o">+</span> <span class="n">arg</span> <span class="o">*</span> <span class="n">jump_multiplier</span>
<span class="n">jmp_state</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;POP_JUMP_BACKWARD_IF_NONE&#39;</span><span class="p">,</span>
<span class="s1">&#39;POP_JUMP_BACKWARD_IF_NOT_NONE&#39;</span><span class="p">):</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="n">jmp</span> <span class="o">=</span> <span class="n">pc</span> <span class="o">-</span> <span class="p">(</span><span class="n">arg</span> <span class="o">*</span> <span class="n">jump_multiplier</span><span class="p">)</span>
<span class="n">jmp_state</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;JUMP_IF_TRUE_OR_POP&#39;</span><span class="p">,</span> <span class="s1">&#39;JUMP_IF_FALSE_OR_POP&#39;</span><span class="p">):</span>
<span class="c1"># The arg was changed to be a relative delta instead of an absolute</span>
<span class="c1"># in 3.11</span>
<span class="k">if</span> <span class="p">(</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="p">,</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="p">)</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">11</span><span class="p">):</span>
<span class="n">jmp</span> <span class="o">=</span> <span class="n">pc</span> <span class="o">+</span> <span class="n">arg</span> <span class="o">*</span> <span class="n">jump_multiplier</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">jmp</span> <span class="o">=</span> <span class="n">arg</span> <span class="o">*</span> <span class="n">jump_multiplier</span>
<span class="n">jmp_state</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;FOR_ITER&#39;</span><span class="p">:</span>
<span class="n">jmp</span> <span class="o">=</span> <span class="n">pc</span> <span class="o">+</span> <span class="n">arg</span> <span class="o">*</span> <span class="n">jump_multiplier</span>
<span class="n">jmp_state</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="n">jmp_state</span><span class="o">.</span><span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">element_type</span><span class="p">(</span><span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]))</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;COPY_FREE_VARS&#39;</span><span class="p">:</span>
<span class="c1"># Helps with calling closures, but since we aren&#39;t executing</span>
<span class="c1"># them we can treat this as a no-op</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;KW_NAMES&#39;</span><span class="p">:</span>
<span class="n">tup</span> <span class="o">=</span> <span class="n">co</span><span class="o">.</span><span class="n">co_consts</span><span class="p">[</span><span class="n">arg</span><span class="p">]</span>
<span class="n">state</span><span class="o">.</span><span class="n">kw_names</span> <span class="o">=</span> <span class="n">tup</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;RESUME&#39;</span><span class="p">:</span>
<span class="c1"># RESUME is a no-op</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;PUSH_NULL&#39;</span><span class="p">:</span>
<span class="c1"># We&#39;re treating this as a no-op to avoid having to check</span>
<span class="c1"># for extra None values on the stack when we extract return</span>
<span class="c1"># values</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;PRECALL&#39;</span><span class="p">:</span>
<span class="c1"># PRECALL is a no-op.</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;MAKE_CELL&#39;</span><span class="p">:</span>
<span class="c1"># TODO: see if we need to implement cells like this</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;RETURN_GENERATOR&#39;</span><span class="p">:</span>
<span class="c1"># TODO: see what this behavior is supposed to be beyond</span>
<span class="c1"># putting something on the stack to be popped off</span>
<span class="n">state</span><span class="o">.</span><span class="n">stack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s1">&#39;CACHE&#39;</span><span class="p">:</span>
<span class="c1"># No-op introduced in 3.11. Without handling this some</span>
<span class="c1"># instructions have functionally &gt; 2 byte size.</span>
<span class="k">pass</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">TypeInferenceError</span><span class="p">(</span><span class="s1">&#39;unable to handle </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">opname</span><span class="p">)</span>
<span class="k">if</span> <span class="n">jmp</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="c1"># TODO(robertwb): Is this guaranteed to converge?</span>
<span class="n">new_state</span> <span class="o">=</span> <span class="n">states</span><span class="p">[</span><span class="n">jmp</span><span class="p">]</span> <span class="o">|</span> <span class="n">jmp_state</span>
<span class="k">if</span> <span class="n">jmp</span> <span class="o">&lt;</span> <span class="n">pc</span> <span class="ow">and</span> <span class="n">new_state</span> <span class="o">!=</span> <span class="n">states</span><span class="p">[</span><span class="n">jmp</span><span class="p">]</span> <span class="ow">and</span> <span class="n">jumps</span><span class="p">[</span><span class="n">pc</span><span class="p">]</span> <span class="o">&lt;</span> <span class="mi">5</span><span class="p">:</span>
<span class="n">jumps</span><span class="p">[</span><span class="n">pc</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">pc</span> <span class="o">=</span> <span class="n">jmp</span>
<span class="n">states</span><span class="p">[</span><span class="n">jmp</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_state</span>
<span class="k">if</span> <span class="n">debug</span><span class="p">:</span>
<span class="nb">print</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">state</span><span class="p">)</span>
<span class="n">pprint</span><span class="o">.</span><span class="n">pprint</span><span class="p">(</span><span class="nb">dict</span><span class="p">(</span><span class="n">item</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">states</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">item</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
<span class="k">if</span> <span class="n">yields</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">typehints</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">reduce</span><span class="p">(</span><span class="n">union</span><span class="p">,</span> <span class="n">Const</span><span class="o">.</span><span class="n">unwrap_all</span><span class="p">(</span><span class="n">yields</span><span class="p">))]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">union</span><span class="p">,</span> <span class="n">Const</span><span class="o">.</span><span class="n">unwrap_all</span><span class="p">(</span><span class="n">returns</span><span class="p">))</span>
<span class="n">finalize_hints</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
<span class="k">if</span> <span class="n">debug</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">id</span><span class="p">(</span><span class="n">f</span><span class="p">),</span> <span class="n">input_types</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="n">result</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span></div>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>