mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
3602 lines
No EOL
462 KiB
HTML
3602 lines
No EOL
462 KiB
HTML
<!DOCTYPE html>
|
|
|
|
<html lang="en" data-content_root="../">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>inspect — Evennia latest documentation</title>
|
|
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d75fae25" />
|
|
<link rel="stylesheet" type="text/css" href="../_static/nature.css?v=279e0f84" />
|
|
<link rel="stylesheet" type="text/css" href="../_static/custom.css?v=e4a91a55" />
|
|
<script src="../_static/documentation_options.js?v=c6e86fd7"></script>
|
|
<script src="../_static/doctools.js?v=9bcbadda"></script>
|
|
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
|
<link rel="icon" href="../_static/favicon.ico"/>
|
|
<link rel="index" title="Index" href="../genindex.html" />
|
|
<link rel="search" title="Search" href="../search.html" />
|
|
</head><body>
|
|
<div class="related" role="navigation" aria-label="Related">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../genindex.html" title="General Index"
|
|
accesskey="I">index</a></li>
|
|
<li class="right" >
|
|
<a href="../py-modindex.html" title="Python Module Index"
|
|
>modules</a> |</li>
|
|
<li class="nav-item nav-item-0"><a href="../index.html">Evennia</a> »</li>
|
|
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Module code</a> »</li>
|
|
<li class="nav-item nav-item-this"><a href="">inspect</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="document">
|
|
<div class="documentwrapper">
|
|
<div class="bodywrapper">
|
|
<div class="body" role="main">
|
|
|
|
<h1>Source code for inspect</h1><div class="highlight"><pre>
|
|
<span></span><span class="sd">"""Get useful information from live Python objects.</span>
|
|
|
|
<span class="sd">This module encapsulates the interface provided by the internal special</span>
|
|
<span class="sd">attributes (co_*, im_*, tb_*, etc.) in a friendlier fashion.</span>
|
|
<span class="sd">It also provides some help for examining source code and class layout.</span>
|
|
|
|
<span class="sd">Here are some of the useful functions provided by this module:</span>
|
|
|
|
<span class="sd"> ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(),</span>
|
|
<span class="sd"> isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(),</span>
|
|
<span class="sd"> isroutine() - check object types</span>
|
|
<span class="sd"> getmembers() - get members of an object that satisfy a given condition</span>
|
|
|
|
<span class="sd"> getfile(), getsourcefile(), getsource() - find an object's source code</span>
|
|
<span class="sd"> getdoc(), getcomments() - get documentation on an object</span>
|
|
<span class="sd"> getmodule() - determine the module that an object came from</span>
|
|
<span class="sd"> getclasstree() - arrange classes so as to represent their hierarchy</span>
|
|
|
|
<span class="sd"> getargvalues(), getcallargs() - get info about function arguments</span>
|
|
<span class="sd"> getfullargspec() - same, with support for Python 3 features</span>
|
|
<span class="sd"> formatargvalues() - format an argument spec</span>
|
|
<span class="sd"> getouterframes(), getinnerframes() - get info about frames</span>
|
|
<span class="sd"> currentframe() - get the current stack frame</span>
|
|
<span class="sd"> stack(), trace() - get info about frames on the stack or in a traceback</span>
|
|
|
|
<span class="sd"> signature() - get a Signature object for the callable</span>
|
|
|
|
<span class="sd"> get_annotations() - safely compute an object's annotations</span>
|
|
<span class="sd">"""</span>
|
|
|
|
<span class="c1"># This module is in the public domain. No warranties.</span>
|
|
|
|
<span class="n">__author__</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'Ka-Ping Yee <ping@lfw.org>'</span><span class="p">,</span>
|
|
<span class="s1">'Yury Selivanov <yselivanov@sprymix.com>'</span><span class="p">)</span>
|
|
|
|
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="s2">"AGEN_CLOSED"</span><span class="p">,</span>
|
|
<span class="s2">"AGEN_CREATED"</span><span class="p">,</span>
|
|
<span class="s2">"AGEN_RUNNING"</span><span class="p">,</span>
|
|
<span class="s2">"AGEN_SUSPENDED"</span><span class="p">,</span>
|
|
<span class="s2">"ArgInfo"</span><span class="p">,</span>
|
|
<span class="s2">"Arguments"</span><span class="p">,</span>
|
|
<span class="s2">"Attribute"</span><span class="p">,</span>
|
|
<span class="s2">"BlockFinder"</span><span class="p">,</span>
|
|
<span class="s2">"BoundArguments"</span><span class="p">,</span>
|
|
<span class="s2">"BufferFlags"</span><span class="p">,</span>
|
|
<span class="s2">"CORO_CLOSED"</span><span class="p">,</span>
|
|
<span class="s2">"CORO_CREATED"</span><span class="p">,</span>
|
|
<span class="s2">"CORO_RUNNING"</span><span class="p">,</span>
|
|
<span class="s2">"CORO_SUSPENDED"</span><span class="p">,</span>
|
|
<span class="s2">"CO_ASYNC_GENERATOR"</span><span class="p">,</span>
|
|
<span class="s2">"CO_COROUTINE"</span><span class="p">,</span>
|
|
<span class="s2">"CO_GENERATOR"</span><span class="p">,</span>
|
|
<span class="s2">"CO_ITERABLE_COROUTINE"</span><span class="p">,</span>
|
|
<span class="s2">"CO_NESTED"</span><span class="p">,</span>
|
|
<span class="s2">"CO_NEWLOCALS"</span><span class="p">,</span>
|
|
<span class="s2">"CO_NOFREE"</span><span class="p">,</span>
|
|
<span class="s2">"CO_OPTIMIZED"</span><span class="p">,</span>
|
|
<span class="s2">"CO_VARARGS"</span><span class="p">,</span>
|
|
<span class="s2">"CO_VARKEYWORDS"</span><span class="p">,</span>
|
|
<span class="s2">"ClassFoundException"</span><span class="p">,</span>
|
|
<span class="s2">"ClosureVars"</span><span class="p">,</span>
|
|
<span class="s2">"EndOfBlock"</span><span class="p">,</span>
|
|
<span class="s2">"FrameInfo"</span><span class="p">,</span>
|
|
<span class="s2">"FullArgSpec"</span><span class="p">,</span>
|
|
<span class="s2">"GEN_CLOSED"</span><span class="p">,</span>
|
|
<span class="s2">"GEN_CREATED"</span><span class="p">,</span>
|
|
<span class="s2">"GEN_RUNNING"</span><span class="p">,</span>
|
|
<span class="s2">"GEN_SUSPENDED"</span><span class="p">,</span>
|
|
<span class="s2">"Parameter"</span><span class="p">,</span>
|
|
<span class="s2">"Signature"</span><span class="p">,</span>
|
|
<span class="s2">"TPFLAGS_IS_ABSTRACT"</span><span class="p">,</span>
|
|
<span class="s2">"Traceback"</span><span class="p">,</span>
|
|
<span class="s2">"classify_class_attrs"</span><span class="p">,</span>
|
|
<span class="s2">"cleandoc"</span><span class="p">,</span>
|
|
<span class="s2">"currentframe"</span><span class="p">,</span>
|
|
<span class="s2">"findsource"</span><span class="p">,</span>
|
|
<span class="s2">"formatannotation"</span><span class="p">,</span>
|
|
<span class="s2">"formatannotationrelativeto"</span><span class="p">,</span>
|
|
<span class="s2">"formatargvalues"</span><span class="p">,</span>
|
|
<span class="s2">"get_annotations"</span><span class="p">,</span>
|
|
<span class="s2">"getabsfile"</span><span class="p">,</span>
|
|
<span class="s2">"getargs"</span><span class="p">,</span>
|
|
<span class="s2">"getargvalues"</span><span class="p">,</span>
|
|
<span class="s2">"getasyncgenlocals"</span><span class="p">,</span>
|
|
<span class="s2">"getasyncgenstate"</span><span class="p">,</span>
|
|
<span class="s2">"getattr_static"</span><span class="p">,</span>
|
|
<span class="s2">"getblock"</span><span class="p">,</span>
|
|
<span class="s2">"getcallargs"</span><span class="p">,</span>
|
|
<span class="s2">"getclasstree"</span><span class="p">,</span>
|
|
<span class="s2">"getclosurevars"</span><span class="p">,</span>
|
|
<span class="s2">"getcomments"</span><span class="p">,</span>
|
|
<span class="s2">"getcoroutinelocals"</span><span class="p">,</span>
|
|
<span class="s2">"getcoroutinestate"</span><span class="p">,</span>
|
|
<span class="s2">"getdoc"</span><span class="p">,</span>
|
|
<span class="s2">"getfile"</span><span class="p">,</span>
|
|
<span class="s2">"getframeinfo"</span><span class="p">,</span>
|
|
<span class="s2">"getfullargspec"</span><span class="p">,</span>
|
|
<span class="s2">"getgeneratorlocals"</span><span class="p">,</span>
|
|
<span class="s2">"getgeneratorstate"</span><span class="p">,</span>
|
|
<span class="s2">"getinnerframes"</span><span class="p">,</span>
|
|
<span class="s2">"getlineno"</span><span class="p">,</span>
|
|
<span class="s2">"getmembers"</span><span class="p">,</span>
|
|
<span class="s2">"getmembers_static"</span><span class="p">,</span>
|
|
<span class="s2">"getmodule"</span><span class="p">,</span>
|
|
<span class="s2">"getmodulename"</span><span class="p">,</span>
|
|
<span class="s2">"getmro"</span><span class="p">,</span>
|
|
<span class="s2">"getouterframes"</span><span class="p">,</span>
|
|
<span class="s2">"getsource"</span><span class="p">,</span>
|
|
<span class="s2">"getsourcefile"</span><span class="p">,</span>
|
|
<span class="s2">"getsourcelines"</span><span class="p">,</span>
|
|
<span class="s2">"indentsize"</span><span class="p">,</span>
|
|
<span class="s2">"isabstract"</span><span class="p">,</span>
|
|
<span class="s2">"isasyncgen"</span><span class="p">,</span>
|
|
<span class="s2">"isasyncgenfunction"</span><span class="p">,</span>
|
|
<span class="s2">"isawaitable"</span><span class="p">,</span>
|
|
<span class="s2">"isbuiltin"</span><span class="p">,</span>
|
|
<span class="s2">"isclass"</span><span class="p">,</span>
|
|
<span class="s2">"iscode"</span><span class="p">,</span>
|
|
<span class="s2">"iscoroutine"</span><span class="p">,</span>
|
|
<span class="s2">"iscoroutinefunction"</span><span class="p">,</span>
|
|
<span class="s2">"isdatadescriptor"</span><span class="p">,</span>
|
|
<span class="s2">"isframe"</span><span class="p">,</span>
|
|
<span class="s2">"isfunction"</span><span class="p">,</span>
|
|
<span class="s2">"isgenerator"</span><span class="p">,</span>
|
|
<span class="s2">"isgeneratorfunction"</span><span class="p">,</span>
|
|
<span class="s2">"isgetsetdescriptor"</span><span class="p">,</span>
|
|
<span class="s2">"ismemberdescriptor"</span><span class="p">,</span>
|
|
<span class="s2">"ismethod"</span><span class="p">,</span>
|
|
<span class="s2">"ismethoddescriptor"</span><span class="p">,</span>
|
|
<span class="s2">"ismethodwrapper"</span><span class="p">,</span>
|
|
<span class="s2">"ismodule"</span><span class="p">,</span>
|
|
<span class="s2">"isroutine"</span><span class="p">,</span>
|
|
<span class="s2">"istraceback"</span><span class="p">,</span>
|
|
<span class="s2">"markcoroutinefunction"</span><span class="p">,</span>
|
|
<span class="s2">"signature"</span><span class="p">,</span>
|
|
<span class="s2">"stack"</span><span class="p">,</span>
|
|
<span class="s2">"trace"</span><span class="p">,</span>
|
|
<span class="s2">"unwrap"</span><span class="p">,</span>
|
|
<span class="s2">"walktree"</span><span class="p">,</span>
|
|
<span class="p">]</span>
|
|
|
|
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">abc</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">ast</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">dis</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">collections.abc</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">enum</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">importlib.machinery</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">itertools</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">linecache</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">re</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">sys</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">tokenize</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">token</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">types</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">functools</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">builtins</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">keyword</span><span class="w"> </span><span class="kn">import</span> <span class="n">iskeyword</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">operator</span><span class="w"> </span><span class="kn">import</span> <span class="n">attrgetter</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">collections</span><span class="w"> </span><span class="kn">import</span> <span class="n">namedtuple</span><span class="p">,</span> <span class="n">OrderedDict</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">weakref</span><span class="w"> </span><span class="kn">import</span> <span class="n">ref</span> <span class="k">as</span> <span class="n">make_weakref</span>
|
|
|
|
<span class="c1"># Create constants for the compiler flags in Include/code.h</span>
|
|
<span class="c1"># We try to get them from dis to avoid duplication</span>
|
|
<span class="n">mod_dict</span> <span class="o">=</span> <span class="nb">globals</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">dis</span><span class="o">.</span><span class="n">COMPILER_FLAG_NAMES</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="n">mod_dict</span><span class="p">[</span><span class="s2">"CO_"</span> <span class="o">+</span> <span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">k</span>
|
|
<span class="k">del</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">mod_dict</span>
|
|
|
|
<span class="c1"># See Include/object.h</span>
|
|
<span class="n">TPFLAGS_IS_ABSTRACT</span> <span class="o">=</span> <span class="mi">1</span> <span class="o"><<</span> <span class="mi">20</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_annotations</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="nb">globals</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="nb">locals</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">eval_str</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Compute the annotations dict for an object.</span>
|
|
|
|
<span class="sd"> obj may be a callable, class, or module.</span>
|
|
<span class="sd"> Passing in an object of any other type raises TypeError.</span>
|
|
|
|
<span class="sd"> Returns a dict. get_annotations() returns a new dict every time</span>
|
|
<span class="sd"> it's called; calling it twice on the same object will return two</span>
|
|
<span class="sd"> different but equivalent dicts.</span>
|
|
|
|
<span class="sd"> This function handles several details for you:</span>
|
|
|
|
<span class="sd"> * If eval_str is true, values of type str will</span>
|
|
<span class="sd"> be un-stringized using eval(). This is intended</span>
|
|
<span class="sd"> for use with stringized annotations</span>
|
|
<span class="sd"> ("from __future__ import annotations").</span>
|
|
<span class="sd"> * If obj doesn't have an annotations dict, returns an</span>
|
|
<span class="sd"> empty dict. (Functions and methods always have an</span>
|
|
<span class="sd"> annotations dict; classes, modules, and other types of</span>
|
|
<span class="sd"> callables may not.)</span>
|
|
<span class="sd"> * Ignores inherited annotations on classes. If a class</span>
|
|
<span class="sd"> doesn't have its own annotations dict, returns an empty dict.</span>
|
|
<span class="sd"> * All accesses to object members and dict values are done</span>
|
|
<span class="sd"> using getattr() and dict.get() for safety.</span>
|
|
<span class="sd"> * Always, always, always returns a freshly-created dict.</span>
|
|
|
|
<span class="sd"> eval_str controls whether or not values of type str are replaced</span>
|
|
<span class="sd"> with the result of calling eval() on those values:</span>
|
|
|
|
<span class="sd"> * If eval_str is true, eval() is called on values of type str.</span>
|
|
<span class="sd"> * If eval_str is false (the default), values of type str are unchanged.</span>
|
|
|
|
<span class="sd"> globals and locals are passed in to eval(); see the documentation</span>
|
|
<span class="sd"> for eval() for more information. If either globals or locals is</span>
|
|
<span class="sd"> None, this function may replace that value with a context-specific</span>
|
|
<span class="sd"> default, contingent on type(obj):</span>
|
|
|
|
<span class="sd"> * If obj is a module, globals defaults to obj.__dict__.</span>
|
|
<span class="sd"> * If obj is a class, globals defaults to</span>
|
|
<span class="sd"> sys.modules[obj.__module__].__dict__ and locals</span>
|
|
<span class="sd"> defaults to the obj class namespace.</span>
|
|
<span class="sd"> * If obj is a callable, globals defaults to obj.__globals__,</span>
|
|
<span class="sd"> although if obj is a wrapped function (using</span>
|
|
<span class="sd"> functools.update_wrapper()) it is first unwrapped.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="c1"># class</span>
|
|
<span class="n">obj_dict</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__dict__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">obj_dict</span> <span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">obj_dict</span><span class="p">,</span> <span class="s1">'get'</span><span class="p">):</span>
|
|
<span class="n">ann</span> <span class="o">=</span> <span class="n">obj_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__annotations__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">ann</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">GetSetDescriptorType</span><span class="p">):</span>
|
|
<span class="n">ann</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">ann</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="n">obj_globals</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">module_name</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">module_name</span><span class="p">:</span>
|
|
<span class="n">module</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">module_name</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">module</span><span class="p">:</span>
|
|
<span class="n">obj_globals</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="s1">'__dict__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">obj_locals</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="nb">vars</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
|
|
<span class="n">unwrap</span> <span class="o">=</span> <span class="n">obj</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">ModuleType</span><span class="p">):</span>
|
|
<span class="c1"># module</span>
|
|
<span class="n">ann</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__annotations__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">obj_globals</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__dict__'</span><span class="p">)</span>
|
|
<span class="n">obj_locals</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">unwrap</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">elif</span> <span class="nb">callable</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="c1"># this includes types.Function, types.BuiltinFunctionType,</span>
|
|
<span class="c1"># types.BuiltinMethodType, functools.partial, functools.singledispatch,</span>
|
|
<span class="c1"># "class funclike" from Lib/test/test_inspect... on and on it goes.</span>
|
|
<span class="n">ann</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__annotations__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">obj_globals</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__globals__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">obj_locals</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">unwrap</span> <span class="o">=</span> <span class="n">obj</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">obj</span><span class="si">!r}</span><span class="s2"> is not a module, class, or callable."</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">ann</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="p">{}</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">ann</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">obj</span><span class="si">!r}</span><span class="s2">.__annotations__ is neither a dict nor None"</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">ann</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="p">{}</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">eval_str</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="n">ann</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">unwrap</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">unwrap</span><span class="p">,</span> <span class="s1">'__wrapped__'</span><span class="p">):</span>
|
|
<span class="n">unwrap</span> <span class="o">=</span> <span class="n">unwrap</span><span class="o">.</span><span class="n">__wrapped__</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">unwrap</span><span class="p">,</span> <span class="n">functools</span><span class="o">.</span><span class="n">partial</span><span class="p">):</span>
|
|
<span class="n">unwrap</span> <span class="o">=</span> <span class="n">unwrap</span><span class="o">.</span><span class="n">func</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">break</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">unwrap</span><span class="p">,</span> <span class="s2">"__globals__"</span><span class="p">):</span>
|
|
<span class="n">obj_globals</span> <span class="o">=</span> <span class="n">unwrap</span><span class="o">.</span><span class="vm">__globals__</span>
|
|
|
|
<span class="k">if</span> <span class="nb">globals</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="nb">globals</span> <span class="o">=</span> <span class="n">obj_globals</span>
|
|
<span class="k">if</span> <span class="nb">locals</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="nb">locals</span> <span class="o">=</span> <span class="n">obj_locals</span> <span class="ow">or</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># "Inject" type parameters into the local namespace</span>
|
|
<span class="c1"># (unless they are shadowed by assignments *in* the local namespace),</span>
|
|
<span class="c1"># as a way of emulating annotation scopes when calling `eval()`</span>
|
|
<span class="k">if</span> <span class="n">type_params</span> <span class="o">:=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s2">"__type_params__"</span><span class="p">,</span> <span class="p">()):</span>
|
|
<span class="nb">locals</span> <span class="o">=</span> <span class="p">{</span><span class="n">param</span><span class="o">.</span><span class="vm">__name__</span><span class="p">:</span> <span class="n">param</span> <span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">type_params</span><span class="p">}</span> <span class="o">|</span> <span class="nb">locals</span>
|
|
|
|
<span class="n">return_value</span> <span class="o">=</span> <span class="p">{</span><span class="n">key</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="nb">eval</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">globals</span><span class="p">,</span> <span class="nb">locals</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">ann</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="p">}</span>
|
|
<span class="k">return</span> <span class="n">return_value</span>
|
|
|
|
|
|
<span class="c1"># ----------------------------------------------------------- type-checking</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">ismodule</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a module."""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">ModuleType</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isclass</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a class."""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="nb">type</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">ismethod</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is an instance method."""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</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">def</span><span class="w"> </span><span class="nf">ismethoddescriptor</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a method descriptor.</span>
|
|
|
|
<span class="sd"> But not if ismethod() or isclass() or isfunction() are true.</span>
|
|
|
|
<span class="sd"> This is new in Python 2.2, and, for example, is true of int.__add__.</span>
|
|
<span class="sd"> An object passing this test has a __get__ attribute, but not a</span>
|
|
<span class="sd"> __set__ attribute or a __delete__ attribute. Beyond that, the set</span>
|
|
<span class="sd"> of attributes varies; __name__ is usually sensible, and __doc__</span>
|
|
<span class="sd"> often is.</span>
|
|
|
|
<span class="sd"> Methods implemented via descriptors that also pass one of the other</span>
|
|
<span class="sd"> tests return false from the ismethoddescriptor() test, simply because</span>
|
|
<span class="sd"> the other tests promise more -- you can, e.g., count on having the</span>
|
|
<span class="sd"> __func__ attribute (etc) when an object passes ismethod()."""</span>
|
|
<span class="k">if</span> <span class="n">isclass</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span> <span class="ow">or</span> <span class="n">ismethod</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span> <span class="ow">or</span> <span class="n">isfunction</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="c1"># mutual exclusion</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">functools</span><span class="o">.</span><span class="n">partial</span><span class="p">):</span>
|
|
<span class="c1"># Lie for children. The addition of partial.__get__</span>
|
|
<span class="c1"># doesn't currently change the partial objects behaviour,</span>
|
|
<span class="c1"># not counting a warning about future changes.</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
<span class="n">tp</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="nb">hasattr</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="s2">"__get__"</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="s2">"__set__"</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="s2">"__delete__"</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isdatadescriptor</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a data descriptor.</span>
|
|
|
|
<span class="sd"> Data descriptors have a __set__ or a __delete__ attribute. Examples are</span>
|
|
<span class="sd"> properties (defined in Python) and getsets and members (defined in C).</span>
|
|
<span class="sd"> Typically, data descriptors will also have __name__ and __doc__ attributes</span>
|
|
<span class="sd"> (properties, getsets, and members have both of these attributes), but this</span>
|
|
<span class="sd"> is not guaranteed."""</span>
|
|
<span class="k">if</span> <span class="n">isclass</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span> <span class="ow">or</span> <span class="n">ismethod</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span> <span class="ow">or</span> <span class="n">isfunction</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="c1"># mutual exclusion</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
<span class="n">tp</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="s2">"__set__"</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">tp</span><span class="p">,</span> <span class="s2">"__delete__"</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">types</span><span class="p">,</span> <span class="s1">'MemberDescriptorType'</span><span class="p">):</span>
|
|
<span class="c1"># CPython and equivalent</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">ismemberdescriptor</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a member descriptor.</span>
|
|
|
|
<span class="sd"> Member descriptors are specialized descriptors defined in extension</span>
|
|
<span class="sd"> modules."""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">MemberDescriptorType</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># Other implementations</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">ismemberdescriptor</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a member descriptor.</span>
|
|
|
|
<span class="sd"> Member descriptors are specialized descriptors defined in extension</span>
|
|
<span class="sd"> modules."""</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">types</span><span class="p">,</span> <span class="s1">'GetSetDescriptorType'</span><span class="p">):</span>
|
|
<span class="c1"># CPython and equivalent</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isgetsetdescriptor</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a getset descriptor.</span>
|
|
|
|
<span class="sd"> getset descriptors are specialized descriptors defined in extension</span>
|
|
<span class="sd"> modules."""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">GetSetDescriptorType</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># Other implementations</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isgetsetdescriptor</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a getset descriptor.</span>
|
|
|
|
<span class="sd"> getset descriptors are specialized descriptors defined in extension</span>
|
|
<span class="sd"> modules."""</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isfunction</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a user-defined function.</span>
|
|
|
|
<span class="sd"> Function objects provide these attributes:</span>
|
|
<span class="sd"> __doc__ documentation string</span>
|
|
<span class="sd"> __name__ name with which this function was defined</span>
|
|
<span class="sd"> __code__ code object containing compiled function bytecode</span>
|
|
<span class="sd"> __defaults__ tuple of any default values for arguments</span>
|
|
<span class="sd"> __globals__ global namespace in which this function was defined</span>
|
|
<span class="sd"> __annotations__ dict of parameter annotations</span>
|
|
<span class="sd"> __kwdefaults__ dict of keyword only parameters with defaults"""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</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">def</span><span class="w"> </span><span class="nf">_has_code_flag</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">flag</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if ``f`` is a function (or a method or functools.partial</span>
|
|
<span class="sd"> wrapper wrapping a function or a functools.partialmethod wrapping a</span>
|
|
<span class="sd"> function) whose code object has the given ``flag``</span>
|
|
<span class="sd"> set in its flags."""</span>
|
|
<span class="n">f</span> <span class="o">=</span> <span class="n">functools</span><span class="o">.</span><span class="n">_unwrap_partialmethod</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
|
|
<span class="k">while</span> <span class="n">ismethod</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
|
|
<span class="n">f</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="vm">__func__</span>
|
|
<span class="n">f</span> <span class="o">=</span> <span class="n">functools</span><span class="o">.</span><span class="n">_unwrap_partial</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">isfunction</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_signature_is_functionlike</span><span class="p">(</span><span class="n">f</span><span class="p">)):</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="vm">__code__</span><span class="o">.</span><span class="n">co_flags</span> <span class="o">&</span> <span class="n">flag</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isgeneratorfunction</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a user-defined generator function.</span>
|
|
|
|
<span class="sd"> Generator function objects provide the same attributes as functions.</span>
|
|
<span class="sd"> See help(isfunction) for a list of attributes."""</span>
|
|
<span class="k">return</span> <span class="n">_has_code_flag</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">CO_GENERATOR</span><span class="p">)</span>
|
|
|
|
<span class="c1"># A marker for markcoroutinefunction and iscoroutinefunction.</span>
|
|
<span class="n">_is_coroutine_mark</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_has_coroutine_mark</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
|
|
<span class="k">while</span> <span class="n">ismethod</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
|
|
<span class="n">f</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="vm">__func__</span>
|
|
<span class="n">f</span> <span class="o">=</span> <span class="n">functools</span><span class="o">.</span><span class="n">_unwrap_partial</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s2">"_is_coroutine_marker"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="ow">is</span> <span class="n">_is_coroutine_mark</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">markcoroutinefunction</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Decorator to ensure callable is recognised as a coroutine function.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s1">'__func__'</span><span class="p">):</span>
|
|
<span class="n">func</span> <span class="o">=</span> <span class="n">func</span><span class="o">.</span><span class="vm">__func__</span>
|
|
<span class="n">func</span><span class="o">.</span><span class="n">_is_coroutine_marker</span> <span class="o">=</span> <span class="n">_is_coroutine_mark</span>
|
|
<span class="k">return</span> <span class="n">func</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">iscoroutinefunction</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a coroutine function.</span>
|
|
|
|
<span class="sd"> Coroutine functions are normally defined with "async def" syntax, but may</span>
|
|
<span class="sd"> be marked via markcoroutinefunction.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">_has_code_flag</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">CO_COROUTINE</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_has_coroutine_mark</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isasyncgenfunction</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is an asynchronous generator function.</span>
|
|
|
|
<span class="sd"> Asynchronous generator functions are defined with "async def"</span>
|
|
<span class="sd"> syntax and have "yield" expressions in their body.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">_has_code_flag</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">CO_ASYNC_GENERATOR</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isasyncgen</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is an asynchronous generator."""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">AsyncGeneratorType</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isgenerator</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a generator.</span>
|
|
|
|
<span class="sd"> Generator objects provide these attributes:</span>
|
|
<span class="sd"> __iter__ defined to support iteration over container</span>
|
|
<span class="sd"> close raises a new GeneratorExit exception inside the</span>
|
|
<span class="sd"> generator to terminate the iteration</span>
|
|
<span class="sd"> gi_code code object</span>
|
|
<span class="sd"> gi_frame frame object or possibly None once the generator has</span>
|
|
<span class="sd"> been exhausted</span>
|
|
<span class="sd"> gi_running set to 1 when generator is executing, 0 otherwise</span>
|
|
<span class="sd"> gi_suspended set to 1 when the generator is suspended at a yield point, 0 otherwise</span>
|
|
<span class="sd"> gi_yieldfrom object being iterated by yield from or None</span>
|
|
<span class="sd"> next return the next item from the container</span>
|
|
<span class="sd"> send resumes the generator and "sends" a value that becomes</span>
|
|
<span class="sd"> the result of the current yield-expression</span>
|
|
<span class="sd"> throw used to raise an exception inside the generator"""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">GeneratorType</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">iscoroutine</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a coroutine."""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">CoroutineType</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isawaitable</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if object can be passed to an ``await`` expression."""</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">CoroutineType</span><span class="p">)</span> <span class="ow">or</span>
|
|
<span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">GeneratorType</span><span class="p">)</span> <span class="ow">and</span>
|
|
<span class="nb">bool</span><span class="p">(</span><span class="nb">object</span><span class="o">.</span><span class="n">gi_code</span><span class="o">.</span><span class="n">co_flags</span> <span class="o">&</span> <span class="n">CO_ITERABLE_COROUTINE</span><span class="p">)</span> <span class="ow">or</span>
|
|
<span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">collections</span><span class="o">.</span><span class="n">abc</span><span class="o">.</span><span class="n">Awaitable</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">istraceback</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a traceback.</span>
|
|
|
|
<span class="sd"> Traceback objects provide these attributes:</span>
|
|
<span class="sd"> tb_frame frame object at this level</span>
|
|
<span class="sd"> tb_lasti index of last attempted instruction in bytecode</span>
|
|
<span class="sd"> tb_lineno current line number in Python source code</span>
|
|
<span class="sd"> tb_next next inner traceback object (called by this level)"""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">TracebackType</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isframe</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a frame object.</span>
|
|
|
|
<span class="sd"> Frame objects provide these attributes:</span>
|
|
<span class="sd"> f_back next outer frame object (this frame's caller)</span>
|
|
<span class="sd"> f_builtins built-in namespace seen by this frame</span>
|
|
<span class="sd"> f_code code object being executed in this frame</span>
|
|
<span class="sd"> f_globals global namespace seen by this frame</span>
|
|
<span class="sd"> f_lasti index of last attempted instruction in bytecode</span>
|
|
<span class="sd"> f_lineno current line number in Python source code</span>
|
|
<span class="sd"> f_locals local namespace seen by this frame</span>
|
|
<span class="sd"> f_trace tracing function for this frame, or None"""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">FrameType</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">iscode</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a code object.</span>
|
|
|
|
<span class="sd"> Code objects provide these attributes:</span>
|
|
<span class="sd"> co_argcount number of arguments (not including *, ** args</span>
|
|
<span class="sd"> or keyword only arguments)</span>
|
|
<span class="sd"> co_code string of raw compiled bytecode</span>
|
|
<span class="sd"> co_cellvars tuple of names of cell variables</span>
|
|
<span class="sd"> co_consts tuple of constants used in the bytecode</span>
|
|
<span class="sd"> co_filename name of file in which this code object was created</span>
|
|
<span class="sd"> co_firstlineno number of first line in Python source code</span>
|
|
<span class="sd"> co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg</span>
|
|
<span class="sd"> | 16=nested | 32=generator | 64=nofree | 128=coroutine</span>
|
|
<span class="sd"> | 256=iterable_coroutine | 512=async_generator</span>
|
|
<span class="sd"> co_freevars tuple of names of free variables</span>
|
|
<span class="sd"> co_posonlyargcount number of positional only arguments</span>
|
|
<span class="sd"> co_kwonlyargcount number of keyword only arguments (not including ** arg)</span>
|
|
<span class="sd"> co_lnotab encoded mapping of line numbers to bytecode indices</span>
|
|
<span class="sd"> co_name name with which this code object was defined</span>
|
|
<span class="sd"> co_names tuple of names other than arguments and function locals</span>
|
|
<span class="sd"> co_nlocals number of local variables</span>
|
|
<span class="sd"> co_stacksize virtual machine stack space required</span>
|
|
<span class="sd"> co_varnames tuple of names of arguments and local variables"""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">CodeType</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isbuiltin</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a built-in function or method.</span>
|
|
|
|
<span class="sd"> Built-in functions and methods provide these attributes:</span>
|
|
<span class="sd"> __doc__ documentation string</span>
|
|
<span class="sd"> __name__ original name of this function or method</span>
|
|
<span class="sd"> __self__ instance to which a method is bound, or None"""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">BuiltinFunctionType</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">ismethodwrapper</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is a method wrapper."""</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">MethodWrapperType</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isroutine</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is any kind of function or method."""</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="n">isbuiltin</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="ow">or</span> <span class="n">isfunction</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="ow">or</span> <span class="n">ismethod</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="ow">or</span> <span class="n">ismethoddescriptor</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="ow">or</span> <span class="n">ismethodwrapper</span><span class="p">(</span><span class="nb">object</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">isabstract</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return true if the object is an abstract base class (ABC)."""</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
<span class="k">if</span> <span class="nb">object</span><span class="o">.</span><span class="n">__flags__</span> <span class="o">&</span> <span class="n">TPFLAGS_IS_ABSTRACT</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">issubclass</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="nb">object</span><span class="p">),</span> <span class="n">abc</span><span class="o">.</span><span class="n">ABCMeta</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="s1">'__abstractmethods__'</span><span class="p">):</span>
|
|
<span class="c1"># It looks like ABCMeta.__new__ has finished running;</span>
|
|
<span class="c1"># TPFLAGS_IS_ABSTRACT should have been accurate.</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
<span class="c1"># It looks like ABCMeta.__new__ has not finished running yet; we're</span>
|
|
<span class="c1"># probably in __init_subclass__. We'll look for abstractmethods manually.</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="nb">object</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="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="s2">"__isabstractmethod__"</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__bases__</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="s2">"__abstractmethods__"</span><span class="p">,</span> <span class="p">()):</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="s2">"__isabstractmethod__"</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_getmembers</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">predicate</span><span class="p">,</span> <span class="n">getter</span><span class="p">):</span>
|
|
<span class="n">results</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">processed</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="n">names</span> <span class="o">=</span> <span class="nb">dir</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">isclass</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="n">mro</span> <span class="o">=</span> <span class="n">getmro</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="c1"># add any DynamicClassAttributes to the list of names if object is a class;</span>
|
|
<span class="c1"># this may result in duplicate entries if, for example, a virtual</span>
|
|
<span class="c1"># attribute with the same name as a DynamicClassAttribute exists</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__bases__</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">base</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="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">DynamicClassAttribute</span><span class="p">):</span>
|
|
<span class="n">names</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">k</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">mro</span> <span class="o">=</span> <span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">names</span><span class="p">:</span>
|
|
<span class="c1"># First try to get the value via getattr. Some descriptors don't</span>
|
|
<span class="c1"># like calling their __get__ (see bug #1785), so fall back to</span>
|
|
<span class="c1"># looking in the __dict__.</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">getter</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
|
|
<span class="c1"># handle the duplicate key</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">processed</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">mro</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># could be a (currently) missing slot member, or a buggy</span>
|
|
<span class="c1"># __dir__; discard and move on</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">predicate</span> <span class="ow">or</span> <span class="n">predicate</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">))</span>
|
|
<span class="n">processed</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
|
|
<span class="n">results</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">pair</span><span class="p">:</span> <span class="n">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
|
<span class="k">return</span> <span class="n">results</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getmembers</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">predicate</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return all members of an object as (name, value) pairs sorted by name.</span>
|
|
<span class="sd"> Optionally, only return members that satisfy a given predicate."""</span>
|
|
<span class="k">return</span> <span class="n">_getmembers</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">predicate</span><span class="p">,</span> <span class="nb">getattr</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getmembers_static</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">predicate</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return all members of an object as (name, value) pairs sorted by name</span>
|
|
<span class="sd"> without triggering dynamic lookup via the descriptor protocol,</span>
|
|
<span class="sd"> __getattr__ or __getattribute__. Optionally, only return members that</span>
|
|
<span class="sd"> satisfy a given predicate.</span>
|
|
|
|
<span class="sd"> Note: this function may not be able to retrieve all members</span>
|
|
<span class="sd"> that getmembers can fetch (like dynamically created attributes)</span>
|
|
<span class="sd"> and may find members that getmembers can't (like descriptors</span>
|
|
<span class="sd"> that raise AttributeError). It can also return descriptor objects</span>
|
|
<span class="sd"> instead of instance members in some cases.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">_getmembers</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">predicate</span><span class="p">,</span> <span class="n">getattr_static</span><span class="p">)</span>
|
|
|
|
<span class="n">Attribute</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'Attribute'</span><span class="p">,</span> <span class="s1">'name kind defining_class object'</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">classify_class_attrs</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return list of attribute-descriptor tuples.</span>
|
|
|
|
<span class="sd"> For each name in dir(cls), the return list contains a 4-tuple</span>
|
|
<span class="sd"> with these elements:</span>
|
|
|
|
<span class="sd"> 0. The name (a string).</span>
|
|
|
|
<span class="sd"> 1. The kind of attribute this is, one of these strings:</span>
|
|
<span class="sd"> 'class method' created via classmethod()</span>
|
|
<span class="sd"> 'static method' created via staticmethod()</span>
|
|
<span class="sd"> 'property' created via property()</span>
|
|
<span class="sd"> 'method' any other flavor of method or descriptor</span>
|
|
<span class="sd"> 'data' not a method</span>
|
|
|
|
<span class="sd"> 2. The class which defined this attribute (a class).</span>
|
|
|
|
<span class="sd"> 3. The object as obtained by calling getattr; if this fails, or if the</span>
|
|
<span class="sd"> resulting object does not live anywhere in the class' mro (including</span>
|
|
<span class="sd"> metaclasses) then the object is looked up in the defining class's</span>
|
|
<span class="sd"> dict (found by walking the mro).</span>
|
|
|
|
<span class="sd"> If one of the items in dir(cls) is stored in the metaclass it will now</span>
|
|
<span class="sd"> be discovered and not have None be listed as the class in which it was</span>
|
|
<span class="sd"> defined. Any items whose home class cannot be discovered are skipped.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">mro</span> <span class="o">=</span> <span class="n">getmro</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span>
|
|
<span class="n">metamro</span> <span class="o">=</span> <span class="n">getmro</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="bp">cls</span><span class="p">))</span> <span class="c1"># for attributes stored in the metaclass</span>
|
|
<span class="n">metamro</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="bp">cls</span> <span class="k">for</span> <span class="bp">cls</span> <span class="ow">in</span> <span class="n">metamro</span> <span class="k">if</span> <span class="bp">cls</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">type</span><span class="p">,</span> <span class="nb">object</span><span class="p">))</span>
|
|
<span class="n">class_bases</span> <span class="o">=</span> <span class="p">(</span><span class="bp">cls</span><span class="p">,)</span> <span class="o">+</span> <span class="n">mro</span>
|
|
<span class="n">all_bases</span> <span class="o">=</span> <span class="n">class_bases</span> <span class="o">+</span> <span class="n">metamro</span>
|
|
<span class="n">names</span> <span class="o">=</span> <span class="nb">dir</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span>
|
|
<span class="c1"># :dd any DynamicClassAttributes to the list of names;</span>
|
|
<span class="c1"># this may result in duplicate entries if, for example, a virtual</span>
|
|
<span class="c1"># attribute with the same name as a DynamicClassAttribute exists.</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">mro</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">base</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="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">DynamicClassAttribute</span><span class="p">)</span> <span class="ow">and</span> <span class="n">v</span><span class="o">.</span><span class="n">fget</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">names</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">k</span><span class="p">)</span>
|
|
<span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">processed</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
|
|
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">names</span><span class="p">:</span>
|
|
<span class="c1"># Get the object associated with the name, and where it was defined.</span>
|
|
<span class="c1"># Normal objects will be looked up with both getattr and directly in</span>
|
|
<span class="c1"># its class' dict (in case getattr fails [bug #1785], and also to look</span>
|
|
<span class="c1"># for a docstring).</span>
|
|
<span class="c1"># For DynamicClassAttributes on the second pass we only look in the</span>
|
|
<span class="c1"># class's dict.</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># Getting an obj from the __dict__ sometimes reveals more than</span>
|
|
<span class="c1"># using getattr. Static and class methods are dramatic examples.</span>
|
|
<span class="n">homecls</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">get_obj</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">dict_obj</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">processed</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s1">'__dict__'</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">"__dict__ is special, don't want the proxy"</span><span class="p">)</span>
|
|
<span class="n">get_obj</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">homecls</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">get_obj</span><span class="p">,</span> <span class="s2">"__objclass__"</span><span class="p">,</span> <span class="n">homecls</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">homecls</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">class_bases</span><span class="p">:</span>
|
|
<span class="c1"># if the resulting object does not live somewhere in the</span>
|
|
<span class="c1"># mro, drop it and search the mro manually</span>
|
|
<span class="n">homecls</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">last_cls</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="c1"># first look in the classes</span>
|
|
<span class="k">for</span> <span class="n">srch_cls</span> <span class="ow">in</span> <span class="n">class_bases</span><span class="p">:</span>
|
|
<span class="n">srch_obj</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">srch_cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">srch_obj</span> <span class="ow">is</span> <span class="n">get_obj</span><span class="p">:</span>
|
|
<span class="n">last_cls</span> <span class="o">=</span> <span class="n">srch_cls</span>
|
|
<span class="c1"># then check the metaclasses</span>
|
|
<span class="k">for</span> <span class="n">srch_cls</span> <span class="ow">in</span> <span class="n">metamro</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">srch_obj</span> <span class="o">=</span> <span class="n">srch_cls</span><span class="o">.</span><span class="fm">__getattr__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">if</span> <span class="n">srch_obj</span> <span class="ow">is</span> <span class="n">get_obj</span><span class="p">:</span>
|
|
<span class="n">last_cls</span> <span class="o">=</span> <span class="n">srch_cls</span>
|
|
<span class="k">if</span> <span class="n">last_cls</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">homecls</span> <span class="o">=</span> <span class="n">last_cls</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">all_bases</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span>
|
|
<span class="n">dict_obj</span> <span class="o">=</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">homecls</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">metamro</span><span class="p">:</span>
|
|
<span class="n">homecls</span> <span class="o">=</span> <span class="n">base</span>
|
|
<span class="k">break</span>
|
|
<span class="k">if</span> <span class="n">homecls</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># unable to locate the attribute anywhere, most likely due to</span>
|
|
<span class="c1"># buggy custom __dir__; discard and move on</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="n">get_obj</span> <span class="k">if</span> <span class="n">get_obj</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">dict_obj</span>
|
|
<span class="c1"># Classify the object or its descriptor.</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">dict_obj</span><span class="p">,</span> <span class="p">(</span><span class="nb">staticmethod</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">BuiltinMethodType</span><span class="p">)):</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="s2">"static method"</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="n">dict_obj</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">dict_obj</span><span class="p">,</span> <span class="p">(</span><span class="nb">classmethod</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">ClassMethodDescriptorType</span><span class="p">)):</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="s2">"class method"</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="n">dict_obj</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">dict_obj</span><span class="p">,</span> <span class="nb">property</span><span class="p">):</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="s2">"property"</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="n">dict_obj</span>
|
|
<span class="k">elif</span> <span class="n">isroutine</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="s2">"method"</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="s2">"data"</span>
|
|
<span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Attribute</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">kind</span><span class="p">,</span> <span class="n">homecls</span><span class="p">,</span> <span class="n">obj</span><span class="p">))</span>
|
|
<span class="n">processed</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">result</span>
|
|
|
|
<span class="c1"># ----------------------------------------------------------- class helpers</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getmro</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="s2">"Return tuple of base classes (including cls) in method resolution order."</span>
|
|
<span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__mro__</span>
|
|
|
|
<span class="c1"># -------------------------------------------------------- function helpers</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">unwrap</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">stop</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get the object wrapped by *func*.</span>
|
|
|
|
<span class="sd"> Follows the chain of :attr:`__wrapped__` attributes returning the last</span>
|
|
<span class="sd"> object in the chain.</span>
|
|
|
|
<span class="sd"> *stop* is an optional callback accepting an object in the wrapper chain</span>
|
|
<span class="sd"> as its sole argument that allows the unwrapping to be terminated early if</span>
|
|
<span class="sd"> the callback returns a true value. If the callback never returns a true</span>
|
|
<span class="sd"> value, the last object in the chain is returned as usual. For example,</span>
|
|
<span class="sd"> :func:`signature` uses this to stop unwrapping if any object in the</span>
|
|
<span class="sd"> chain has a ``__signature__`` attribute defined.</span>
|
|
|
|
<span class="sd"> :exc:`ValueError` is raised if a cycle is encountered.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="n">f</span> <span class="o">=</span> <span class="n">func</span> <span class="c1"># remember the original func for error reporting</span>
|
|
<span class="c1"># Memoise by id to tolerate non-hashable objects, but store objects to</span>
|
|
<span class="c1"># ensure they aren't destroyed, which would allow their IDs to be reused.</span>
|
|
<span class="n">memo</span> <span class="o">=</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">f</span><span class="p">}</span>
|
|
<span class="n">recursion_limit</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">getrecursionlimit</span><span class="p">()</span>
|
|
<span class="k">while</span> <span class="ow">not</span> <span class="nb">isinstance</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="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s1">'__wrapped__'</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">stop</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">stop</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="k">break</span>
|
|
<span class="n">func</span> <span class="o">=</span> <span class="n">func</span><span class="o">.</span><span class="n">__wrapped__</span>
|
|
<span class="n">id_func</span> <span class="o">=</span> <span class="nb">id</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="n">id_func</span> <span class="ow">in</span> <span class="n">memo</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">memo</span><span class="p">)</span> <span class="o">>=</span> <span class="n">recursion_limit</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'wrapper loop when unwrapping </span><span class="si">{!r}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">f</span><span class="p">))</span>
|
|
<span class="n">memo</span><span class="p">[</span><span class="n">id_func</span><span class="p">]</span> <span class="o">=</span> <span class="n">func</span>
|
|
<span class="k">return</span> <span class="n">func</span>
|
|
|
|
<span class="c1"># -------------------------------------------------- source code extraction</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">indentsize</span><span class="p">(</span><span class="n">line</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return the indent size, in spaces, at the start of a line of text."""</span>
|
|
<span class="n">expline</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">expandtabs</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="n">expline</span><span class="p">)</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">expline</span><span class="o">.</span><span class="n">lstrip</span><span class="p">())</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_findclass</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">func</span><span class="o">.</span><span class="vm">__module__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">cls</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">func</span><span class="o">.</span><span class="vm">__qualname__</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">isclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">return</span> <span class="bp">cls</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_finddoc</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">isclass</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">base</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">object</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">doc</span> <span class="o">=</span> <span class="n">base</span><span class="o">.</span><span class="vm">__doc__</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">doc</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
|
|
<span class="k">if</span> <span class="n">ismethod</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__func__</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="bp">self</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__self__</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="n">isclass</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="ow">and</span>
|
|
<span class="nb">getattr</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span> <span class="s1">'__func__'</span><span class="p">)</span> <span class="ow">is</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__func__</span><span class="p">):</span>
|
|
<span class="c1"># classmethod</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="bp">self</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span>
|
|
<span class="k">elif</span> <span class="n">isfunction</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="n">_findclass</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">cls</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">obj</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">elif</span> <span class="n">isbuiltin</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="bp">self</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__self__</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="n">isclass</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="ow">and</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="vm">__qualname__</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="n">name</span> <span class="o">==</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__qualname__</span><span class="p">):</span>
|
|
<span class="c1"># classmethod</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="bp">self</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span>
|
|
<span class="c1"># Should be tested before isdatadescriptor().</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">property</span><span class="p">):</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="n">_findclass</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">fget</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">cls</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">obj</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">elif</span> <span class="n">ismethoddescriptor</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="ow">or</span> <span class="n">isdatadescriptor</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__objclass__</span>
|
|
<span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">obj</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="n">ismemberdescriptor</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="n">slots</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="s1">'__slots__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">slots</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)</span> <span class="ow">and</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">slots</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">slots</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">doc</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span><span class="o">.</span><span class="vm">__doc__</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">doc</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getdoc</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get the documentation string for an object.</span>
|
|
|
|
<span class="sd"> All tabs are expanded to spaces. To clean up docstrings that are</span>
|
|
<span class="sd"> indented to line up with blocks of code, any whitespace than can be</span>
|
|
<span class="sd"> uniformly removed from the second line onwards is removed."""</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">doc</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__doc__</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">doc</span> <span class="o">=</span> <span class="n">_finddoc</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">AttributeError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">doc</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">return</span> <span class="n">cleandoc</span><span class="p">(</span><span class="n">doc</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">cleandoc</span><span class="p">(</span><span class="n">doc</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Clean up indentation from docstrings.</span>
|
|
|
|
<span class="sd"> Any whitespace that can be uniformly removed from the second line</span>
|
|
<span class="sd"> onwards is removed."""</span>
|
|
<span class="n">lines</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">expandtabs</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Find minimum indentation of any non-blank lines after first line.</span>
|
|
<span class="n">margin</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">maxsize</span>
|
|
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
|
|
<span class="n">content</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s1">' '</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">content</span><span class="p">:</span>
|
|
<span class="n">indent</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="o">-</span> <span class="n">content</span>
|
|
<span class="n">margin</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">margin</span><span class="p">,</span> <span class="n">indent</span><span class="p">)</span>
|
|
<span class="c1"># Remove indentation.</span>
|
|
<span class="k">if</span> <span class="n">lines</span><span class="p">:</span>
|
|
<span class="n">lines</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">lines</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s1">' '</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">margin</span> <span class="o"><</span> <span class="n">sys</span><span class="o">.</span><span class="n">maxsize</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)):</span>
|
|
<span class="n">lines</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">lines</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">margin</span><span class="p">:]</span>
|
|
<span class="c1"># Remove any trailing or leading blank lines.</span>
|
|
<span class="k">while</span> <span class="n">lines</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">lines</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
|
|
<span class="n">lines</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
|
|
<span class="k">while</span> <span class="n">lines</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">lines</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
|
|
<span class="n">lines</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getfile</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Work out which source or compiled file an object was defined in."""</span>
|
|
<span class="k">if</span> <span class="n">ismodule</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="s1">'__file__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__file__</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'</span><span class="si">{!r}</span><span class="s1"> is a built-in module'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">object</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">isclass</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">):</span>
|
|
<span class="n">module</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">object</span><span class="o">.</span><span class="vm">__module__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="s1">'__file__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">module</span><span class="o">.</span><span class="vm">__file__</span>
|
|
<span class="k">if</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__module__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">'source code not available'</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'</span><span class="si">{!r}</span><span class="s1"> is a built-in class'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">object</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">ismethod</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="nb">object</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__func__</span>
|
|
<span class="k">if</span> <span class="n">isfunction</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="nb">object</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__code__</span>
|
|
<span class="k">if</span> <span class="n">istraceback</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="nb">object</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="n">tb_frame</span>
|
|
<span class="k">if</span> <span class="n">isframe</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="nb">object</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="n">f_code</span>
|
|
<span class="k">if</span> <span class="n">iscode</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">object</span><span class="o">.</span><span class="n">co_filename</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'module, class, method, function, traceback, frame, or '</span>
|
|
<span class="s1">'code object was expected, got </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
|
<span class="nb">type</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getmodulename</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return the module name for a given file, or None."""</span>
|
|
<span class="n">fname</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
|
|
<span class="c1"># Check for paths that look like an actual module file</span>
|
|
<span class="n">suffixes</span> <span class="o">=</span> <span class="p">[(</span><span class="o">-</span><span class="nb">len</span><span class="p">(</span><span class="n">suffix</span><span class="p">),</span> <span class="n">suffix</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">suffix</span> <span class="ow">in</span> <span class="n">importlib</span><span class="o">.</span><span class="n">machinery</span><span class="o">.</span><span class="n">all_suffixes</span><span class="p">()]</span>
|
|
<span class="n">suffixes</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span> <span class="c1"># try longest suffixes first, in case they overlap</span>
|
|
<span class="k">for</span> <span class="n">neglen</span><span class="p">,</span> <span class="n">suffix</span> <span class="ow">in</span> <span class="n">suffixes</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">fname</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">suffix</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">fname</span><span class="p">[:</span><span class="n">neglen</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getsourcefile</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return the filename that can be used to locate an object's source.</span>
|
|
<span class="sd"> Return None if no way can be identified to get the source.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">filename</span> <span class="o">=</span> <span class="n">getfile</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="n">all_bytecode_suffixes</span> <span class="o">=</span> <span class="n">importlib</span><span class="o">.</span><span class="n">machinery</span><span class="o">.</span><span class="n">DEBUG_BYTECODE_SUFFIXES</span><span class="p">[:]</span>
|
|
<span class="n">all_bytecode_suffixes</span> <span class="o">+=</span> <span class="n">importlib</span><span class="o">.</span><span class="n">machinery</span><span class="o">.</span><span class="n">OPTIMIZED_BYTECODE_SUFFIXES</span><span class="p">[:]</span>
|
|
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">filename</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">all_bytecode_suffixes</span><span class="p">):</span>
|
|
<span class="n">filename</span> <span class="o">=</span> <span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">filename</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span>
|
|
<span class="n">importlib</span><span class="o">.</span><span class="n">machinery</span><span class="o">.</span><span class="n">SOURCE_SUFFIXES</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
|
<span class="k">elif</span> <span class="nb">any</span><span class="p">(</span><span class="n">filename</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span>
|
|
<span class="n">importlib</span><span class="o">.</span><span class="n">machinery</span><span class="o">.</span><span class="n">EXTENSION_SUFFIXES</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">elif</span> <span class="n">filename</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">".fwork"</span><span class="p">):</span>
|
|
<span class="c1"># Apple mobile framework markers are another type of non-source file</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># return a filename found in the linecache even if it doesn't exist on disk</span>
|
|
<span class="k">if</span> <span class="n">filename</span> <span class="ow">in</span> <span class="n">linecache</span><span class="o">.</span><span class="n">cache</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">filename</span>
|
|
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">filename</span>
|
|
<span class="c1"># only return a non-existent filename if the module has a PEP 302 loader</span>
|
|
<span class="n">module</span> <span class="o">=</span> <span class="n">getmodule</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="s1">'__loader__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">filename</span>
|
|
<span class="k">elif</span> <span class="nb">getattr</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="s2">"__spec__"</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span> <span class="s2">"loader"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">filename</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getabsfile</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">_filename</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return an absolute path to the source or compiled file for an object.</span>
|
|
|
|
<span class="sd"> The idea is for each object to have a unique origin, so this routine</span>
|
|
<span class="sd"> normalizes the result as much as possible."""</span>
|
|
<span class="k">if</span> <span class="n">_filename</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">_filename</span> <span class="o">=</span> <span class="n">getsourcefile</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span> <span class="ow">or</span> <span class="n">getfile</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">normcase</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">_filename</span><span class="p">))</span>
|
|
|
|
<span class="n">modulesbyfile</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">_filesbymodname</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getmodule</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">_filename</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return the module an object was defined in, or None if not found."""</span>
|
|
<span class="k">if</span> <span class="n">ismodule</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">object</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">object</span><span class="o">.</span><span class="vm">__module__</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Try the filename to modulename cache</span>
|
|
<span class="k">if</span> <span class="n">_filename</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">_filename</span> <span class="ow">in</span> <span class="n">modulesbyfile</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">modulesbyfile</span><span class="p">[</span><span class="n">_filename</span><span class="p">])</span>
|
|
<span class="c1"># Try the cache again with the absolute file name</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">file</span> <span class="o">=</span> <span class="n">getabsfile</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">_filename</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">FileNotFoundError</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="n">file</span> <span class="ow">in</span> <span class="n">modulesbyfile</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">modulesbyfile</span><span class="p">[</span><span class="n">file</span><span class="p">])</span>
|
|
<span class="c1"># Update the filename to module name cache and check yet again</span>
|
|
<span class="c1"># Copy sys.modules in order to cope with changes while iterating</span>
|
|
<span class="k">for</span> <span class="n">modname</span><span class="p">,</span> <span class="n">module</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">ismodule</span><span class="p">(</span><span class="n">module</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="s1">'__file__'</span><span class="p">):</span>
|
|
<span class="n">f</span> <span class="o">=</span> <span class="n">module</span><span class="o">.</span><span class="vm">__file__</span>
|
|
<span class="k">if</span> <span class="n">f</span> <span class="o">==</span> <span class="n">_filesbymodname</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">modname</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
|
|
<span class="c1"># Have already mapped this module, so skip it</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">_filesbymodname</span><span class="p">[</span><span class="n">modname</span><span class="p">]</span> <span class="o">=</span> <span class="n">f</span>
|
|
<span class="n">f</span> <span class="o">=</span> <span class="n">getabsfile</span><span class="p">(</span><span class="n">module</span><span class="p">)</span>
|
|
<span class="c1"># Always map to the name the module knows itself by</span>
|
|
<span class="n">modulesbyfile</span><span class="p">[</span><span class="n">f</span><span class="p">]</span> <span class="o">=</span> <span class="n">modulesbyfile</span><span class="p">[</span>
|
|
<span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">f</span><span class="p">)]</span> <span class="o">=</span> <span class="n">module</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="k">if</span> <span class="n">file</span> <span class="ow">in</span> <span class="n">modulesbyfile</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">modulesbyfile</span><span class="p">[</span><span class="n">file</span><span class="p">])</span>
|
|
<span class="c1"># Check the main module</span>
|
|
<span class="n">main</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="s1">'__main__'</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="s1">'__name__'</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">main</span><span class="p">,</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__name__</span><span class="p">):</span>
|
|
<span class="n">mainobject</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">main</span><span class="p">,</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__name__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">mainobject</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">main</span>
|
|
<span class="c1"># Check builtins</span>
|
|
<span class="n">builtin</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="s1">'builtins'</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">builtin</span><span class="p">,</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__name__</span><span class="p">):</span>
|
|
<span class="n">builtinobject</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">builtin</span><span class="p">,</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__name__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">builtinobject</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">builtin</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">ClassFoundException</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">findsource</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return the entire source file and starting line number for an object.</span>
|
|
|
|
<span class="sd"> The argument may be a module, class, method, function, traceback, frame,</span>
|
|
<span class="sd"> or code object. The source code is returned as a list of all the lines</span>
|
|
<span class="sd"> in the file and the line number indexes a line in that list. An OSError</span>
|
|
<span class="sd"> is raised if the source code cannot be retrieved."""</span>
|
|
|
|
<span class="n">file</span> <span class="o">=</span> <span class="n">getsourcefile</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">file</span><span class="p">:</span>
|
|
<span class="c1"># Invalidate cache if needed.</span>
|
|
<span class="n">linecache</span><span class="o">.</span><span class="n">checkcache</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">file</span> <span class="o">=</span> <span class="n">getfile</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="c1"># Allow filenames in form of "<something>" to pass through.</span>
|
|
<span class="c1"># `doctest` monkeypatches `linecache` module to enable</span>
|
|
<span class="c1"># inspection, so let `linecache.getlines` to be called.</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="ow">not</span> <span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'<'</span><span class="p">)</span> <span class="ow">and</span> <span class="n">file</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">'>'</span><span class="p">)))</span> <span class="ow">or</span> <span class="n">file</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">'.fwork'</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">'source code not available'</span><span class="p">)</span>
|
|
|
|
<span class="n">module</span> <span class="o">=</span> <span class="n">getmodule</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">file</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">module</span><span class="p">:</span>
|
|
<span class="n">lines</span> <span class="o">=</span> <span class="n">linecache</span><span class="o">.</span><span class="n">getlines</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">module</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">lines</span> <span class="ow">and</span> <span class="n">file</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'<'</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="s2">"__code__"</span><span class="p">):</span>
|
|
<span class="n">lines</span> <span class="o">=</span> <span class="n">linecache</span><span class="o">.</span><span class="n">_getlines_from_code</span><span class="p">(</span><span class="nb">object</span><span class="o">.</span><span class="vm">__code__</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">lines</span> <span class="o">=</span> <span class="n">linecache</span><span class="o">.</span><span class="n">getlines</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">lines</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">'could not get source code'</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">ismodule</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">lines</span><span class="p">,</span> <span class="mi">0</span>
|
|
|
|
<span class="k">if</span> <span class="n">isclass</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">lnum</span> <span class="o">=</span> <span class="nb">vars</span><span class="p">(</span><span class="nb">object</span><span class="p">)[</span><span class="s1">'__firstlineno__'</span><span class="p">]</span> <span class="o">-</span> <span class="mi">1</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">KeyError</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">'source code not available'</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">lnum</span> <span class="o">>=</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">'lineno is out of bounds'</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">lines</span><span class="p">,</span> <span class="n">lnum</span>
|
|
|
|
<span class="k">if</span> <span class="n">ismethod</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="nb">object</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__func__</span>
|
|
<span class="k">if</span> <span class="n">isfunction</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="nb">object</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="vm">__code__</span>
|
|
<span class="k">if</span> <span class="n">istraceback</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="nb">object</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="n">tb_frame</span>
|
|
<span class="k">if</span> <span class="n">isframe</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="nb">object</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="n">f_code</span>
|
|
<span class="k">if</span> <span class="n">iscode</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="s1">'co_firstlineno'</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">'could not find function definition'</span><span class="p">)</span>
|
|
<span class="n">lnum</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="n">co_firstlineno</span> <span class="o">-</span> <span class="mi">1</span>
|
|
<span class="k">if</span> <span class="n">lnum</span> <span class="o">>=</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">'lineno is out of bounds'</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">lines</span><span class="p">,</span> <span class="n">lnum</span>
|
|
<span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s1">'could not find code object'</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getcomments</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get lines of comments immediately preceding an object's source code.</span>
|
|
|
|
<span class="sd"> Returns None when source can't be found.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">lines</span><span class="p">,</span> <span class="n">lnum</span> <span class="o">=</span> <span class="n">findsource</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">OSError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
|
|
<span class="k">if</span> <span class="n">ismodule</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="c1"># Look for a comment block at the top of the file.</span>
|
|
<span class="n">start</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="k">if</span> <span class="n">lines</span> <span class="ow">and</span> <span class="n">lines</span><span class="p">[</span><span class="mi">0</span><span class="p">][:</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'#!'</span><span class="p">:</span> <span class="n">start</span> <span class="o">=</span> <span class="mi">1</span>
|
|
<span class="k">while</span> <span class="n">start</span> <span class="o"><</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span> <span class="ow">and</span> <span class="n">lines</span><span class="p">[</span><span class="n">start</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">''</span><span class="p">,</span> <span class="s1">'#'</span><span class="p">):</span>
|
|
<span class="n">start</span> <span class="o">=</span> <span class="n">start</span> <span class="o">+</span> <span class="mi">1</span>
|
|
<span class="k">if</span> <span class="n">start</span> <span class="o"><</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span> <span class="ow">and</span> <span class="n">lines</span><span class="p">[</span><span class="n">start</span><span class="p">][:</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'#'</span><span class="p">:</span>
|
|
<span class="n">comments</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">end</span> <span class="o">=</span> <span class="n">start</span>
|
|
<span class="k">while</span> <span class="n">end</span> <span class="o"><</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span> <span class="ow">and</span> <span class="n">lines</span><span class="p">[</span><span class="n">end</span><span class="p">][:</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'#'</span><span class="p">:</span>
|
|
<span class="n">comments</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">lines</span><span class="p">[</span><span class="n">end</span><span class="p">]</span><span class="o">.</span><span class="n">expandtabs</span><span class="p">())</span>
|
|
<span class="n">end</span> <span class="o">=</span> <span class="n">end</span> <span class="o">+</span> <span class="mi">1</span>
|
|
<span class="k">return</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">comments</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Look for a preceding block of comments at the same indentation.</span>
|
|
<span class="k">elif</span> <span class="n">lnum</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="n">indent</span> <span class="o">=</span> <span class="n">indentsize</span><span class="p">(</span><span class="n">lines</span><span class="p">[</span><span class="n">lnum</span><span class="p">])</span>
|
|
<span class="n">end</span> <span class="o">=</span> <span class="n">lnum</span> <span class="o">-</span> <span class="mi">1</span>
|
|
<span class="k">if</span> <span class="n">end</span> <span class="o">>=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">lines</span><span class="p">[</span><span class="n">end</span><span class="p">]</span><span class="o">.</span><span class="n">lstrip</span><span class="p">()[:</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'#'</span> <span class="ow">and</span> \
|
|
<span class="n">indentsize</span><span class="p">(</span><span class="n">lines</span><span class="p">[</span><span class="n">end</span><span class="p">])</span> <span class="o">==</span> <span class="n">indent</span><span class="p">:</span>
|
|
<span class="n">comments</span> <span class="o">=</span> <span class="p">[</span><span class="n">lines</span><span class="p">[</span><span class="n">end</span><span class="p">]</span><span class="o">.</span><span class="n">expandtabs</span><span class="p">()</span><span class="o">.</span><span class="n">lstrip</span><span class="p">()]</span>
|
|
<span class="k">if</span> <span class="n">end</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="n">end</span> <span class="o">=</span> <span class="n">end</span> <span class="o">-</span> <span class="mi">1</span>
|
|
<span class="n">comment</span> <span class="o">=</span> <span class="n">lines</span><span class="p">[</span><span class="n">end</span><span class="p">]</span><span class="o">.</span><span class="n">expandtabs</span><span class="p">()</span><span class="o">.</span><span class="n">lstrip</span><span class="p">()</span>
|
|
<span class="k">while</span> <span class="n">comment</span><span class="p">[:</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'#'</span> <span class="ow">and</span> <span class="n">indentsize</span><span class="p">(</span><span class="n">lines</span><span class="p">[</span><span class="n">end</span><span class="p">])</span> <span class="o">==</span> <span class="n">indent</span><span class="p">:</span>
|
|
<span class="n">comments</span><span class="p">[:</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">comment</span><span class="p">]</span>
|
|
<span class="n">end</span> <span class="o">=</span> <span class="n">end</span> <span class="o">-</span> <span class="mi">1</span>
|
|
<span class="k">if</span> <span class="n">end</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> <span class="k">break</span>
|
|
<span class="n">comment</span> <span class="o">=</span> <span class="n">lines</span><span class="p">[</span><span class="n">end</span><span class="p">]</span><span class="o">.</span><span class="n">expandtabs</span><span class="p">()</span><span class="o">.</span><span class="n">lstrip</span><span class="p">()</span>
|
|
<span class="k">while</span> <span class="n">comments</span> <span class="ow">and</span> <span class="n">comments</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="o">==</span> <span class="s1">'#'</span><span class="p">:</span>
|
|
<span class="n">comments</span><span class="p">[:</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">while</span> <span class="n">comments</span> <span class="ow">and</span> <span class="n">comments</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">strip</span><span class="p">()</span> <span class="o">==</span> <span class="s1">'#'</span><span class="p">:</span>
|
|
<span class="n">comments</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">:]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">return</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">comments</span><span class="p">)</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">EndOfBlock</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span> <span class="k">pass</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">BlockFinder</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Provide a tokeneater() method to detect the end of a code block."""</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">indent</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">singleline</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">started</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">passline</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">indecorator</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">last</span> <span class="o">=</span> <span class="mi">1</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">body_col0</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">tokeneater</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span> <span class="n">srowcol</span><span class="p">,</span> <span class="n">erowcol</span><span class="p">,</span> <span class="n">line</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">started</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">indecorator</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">type</span> <span class="ow">in</span> <span class="p">(</span><span class="n">tokenize</span><span class="o">.</span><span class="n">INDENT</span><span class="p">,</span> <span class="n">tokenize</span><span class="o">.</span><span class="n">COMMENT</span><span class="p">,</span> <span class="n">tokenize</span><span class="o">.</span><span class="n">NL</span><span class="p">):</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">elif</span> <span class="n">token</span> <span class="o">==</span> <span class="s2">"async"</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="c1"># skip any decorators</span>
|
|
<span class="k">elif</span> <span class="n">token</span> <span class="o">==</span> <span class="s2">"@"</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">indecorator</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># For "def" and "class" scan to the end of the block.</span>
|
|
<span class="c1"># For "lambda" and generator expression scan to</span>
|
|
<span class="c1"># the end of the logical line.</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">singleline</span> <span class="o">=</span> <span class="n">token</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"def"</span><span class="p">,</span> <span class="s2">"class"</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">started</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">passline</span> <span class="o">=</span> <span class="kc">True</span> <span class="c1"># skip to the end of the line</span>
|
|
<span class="k">elif</span> <span class="nb">type</span> <span class="o">==</span> <span class="n">tokenize</span><span class="o">.</span><span class="n">NEWLINE</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">passline</span> <span class="o">=</span> <span class="kc">False</span> <span class="c1"># stop skipping when a NEWLINE is seen</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">last</span> <span class="o">=</span> <span class="n">srowcol</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">singleline</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">EndOfBlock</span>
|
|
<span class="c1"># hitting a NEWLINE when in a decorator without args</span>
|
|
<span class="c1"># ends the decorator</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">indecorator</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">indecorator</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">passline</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">elif</span> <span class="nb">type</span> <span class="o">==</span> <span class="n">tokenize</span><span class="o">.</span><span class="n">INDENT</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_col0</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">started</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">body_col0</span> <span class="o">=</span> <span class="n">erowcol</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">indent</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">indent</span> <span class="o">+</span> <span class="mi">1</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">passline</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">elif</span> <span class="nb">type</span> <span class="o">==</span> <span class="n">tokenize</span><span class="o">.</span><span class="n">DEDENT</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">indent</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">indent</span> <span class="o">-</span> <span class="mi">1</span>
|
|
<span class="c1"># the end of matching indent/dedent pairs end a block</span>
|
|
<span class="c1"># (note that this only works for "def"/"class" blocks,</span>
|
|
<span class="c1"># not e.g. for "if: else:" or "try: finally:" blocks)</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">indent</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">EndOfBlock</span>
|
|
<span class="k">elif</span> <span class="nb">type</span> <span class="o">==</span> <span class="n">tokenize</span><span class="o">.</span><span class="n">COMMENT</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_col0</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">srowcol</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">>=</span> <span class="bp">self</span><span class="o">.</span><span class="n">body_col0</span><span class="p">:</span>
|
|
<span class="c1"># Include comments if indented at least as much as the block</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">last</span> <span class="o">=</span> <span class="n">srowcol</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">indent</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="nb">type</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="n">tokenize</span><span class="o">.</span><span class="n">COMMENT</span><span class="p">,</span> <span class="n">tokenize</span><span class="o">.</span><span class="n">NL</span><span class="p">):</span>
|
|
<span class="c1"># any other token on the same indentation level end the previous</span>
|
|
<span class="c1"># block as well, except the pseudo-tokens COMMENT and NL.</span>
|
|
<span class="k">raise</span> <span class="n">EndOfBlock</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getblock</span><span class="p">(</span><span class="n">lines</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Extract the block of code at the top of the given list of lines."""</span>
|
|
<span class="n">blockfinder</span> <span class="o">=</span> <span class="n">BlockFinder</span><span class="p">()</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">tokens</span> <span class="o">=</span> <span class="n">tokenize</span><span class="o">.</span><span class="n">generate_tokens</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span><span class="o">.</span><span class="fm">__next__</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">_token</span> <span class="ow">in</span> <span class="n">tokens</span><span class="p">:</span>
|
|
<span class="n">blockfinder</span><span class="o">.</span><span class="n">tokeneater</span><span class="p">(</span><span class="o">*</span><span class="n">_token</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="n">EndOfBlock</span><span class="p">,</span> <span class="ne">IndentationError</span><span class="p">):</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">except</span> <span class="ne">SyntaxError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="s2">"unmatched"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">e</span><span class="o">.</span><span class="n">msg</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">e</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
|
|
<span class="n">_</span><span class="p">,</span> <span class="o">*</span><span class="n">_token_info</span> <span class="o">=</span> <span class="n">_token</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">blockfinder</span><span class="o">.</span><span class="n">tokeneater</span><span class="p">(</span><span class="n">tokenize</span><span class="o">.</span><span class="n">NEWLINE</span><span class="p">,</span> <span class="o">*</span><span class="n">_token_info</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="n">EndOfBlock</span><span class="p">,</span> <span class="ne">IndentationError</span><span class="p">):</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">return</span> <span class="n">lines</span><span class="p">[:</span><span class="n">blockfinder</span><span class="o">.</span><span class="n">last</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getsourcelines</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return a list of source lines and starting line number for an object.</span>
|
|
|
|
<span class="sd"> The argument may be a module, class, method, function, traceback, frame,</span>
|
|
<span class="sd"> or code object. The source code is returned as a list of the lines</span>
|
|
<span class="sd"> corresponding to the object and the line number indicates where in the</span>
|
|
<span class="sd"> original source file the first line of code was found. An OSError is</span>
|
|
<span class="sd"> raised if the source code cannot be retrieved."""</span>
|
|
<span class="nb">object</span> <span class="o">=</span> <span class="n">unwrap</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="n">lines</span><span class="p">,</span> <span class="n">lnum</span> <span class="o">=</span> <span class="n">findsource</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">istraceback</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="nb">object</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="n">tb_frame</span>
|
|
|
|
<span class="c1"># for module or frame that corresponds to module, return all source lines</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="n">ismodule</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span> <span class="ow">or</span>
|
|
<span class="p">(</span><span class="n">isframe</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">object</span><span class="o">.</span><span class="n">f_code</span><span class="o">.</span><span class="n">co_name</span> <span class="o">==</span> <span class="s2">"<module>"</span><span class="p">)):</span>
|
|
<span class="k">return</span> <span class="n">lines</span><span class="p">,</span> <span class="mi">0</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">getblock</span><span class="p">(</span><span class="n">lines</span><span class="p">[</span><span class="n">lnum</span><span class="p">:]),</span> <span class="n">lnum</span> <span class="o">+</span> <span class="mi">1</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getsource</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return the text of the source code for an object.</span>
|
|
|
|
<span class="sd"> The argument may be a module, class, method, function, traceback, frame,</span>
|
|
<span class="sd"> or code object. The source code is returned as a single string. An</span>
|
|
<span class="sd"> OSError is raised if the source code cannot be retrieved."""</span>
|
|
<span class="n">lines</span><span class="p">,</span> <span class="n">lnum</span> <span class="o">=</span> <span class="n">getsourcelines</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span>
|
|
|
|
<span class="c1"># --------------------------------------------------- class tree extraction</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">walktree</span><span class="p">(</span><span class="n">classes</span><span class="p">,</span> <span class="n">children</span><span class="p">,</span> <span class="n">parent</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Recursive helper function for getclasstree()."""</span>
|
|
<span class="n">results</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">classes</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">attrgetter</span><span class="p">(</span><span class="s1">'__module__'</span><span class="p">,</span> <span class="s1">'__name__'</span><span class="p">))</span>
|
|
<span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">classes</span><span class="p">:</span>
|
|
<span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">c</span><span class="p">,</span> <span class="n">c</span><span class="o">.</span><span class="vm">__bases__</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">children</span><span class="p">:</span>
|
|
<span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">walktree</span><span class="p">(</span><span class="n">children</span><span class="p">[</span><span class="n">c</span><span class="p">],</span> <span class="n">children</span><span class="p">,</span> <span class="n">c</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">results</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getclasstree</span><span class="p">(</span><span class="n">classes</span><span class="p">,</span> <span class="n">unique</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Arrange the given list of classes into a hierarchy of nested lists.</span>
|
|
|
|
<span class="sd"> Where a nested list appears, it contains classes derived from the class</span>
|
|
<span class="sd"> whose entry immediately precedes the list. Each entry is a 2-tuple</span>
|
|
<span class="sd"> containing a class and a tuple of its base classes. If the 'unique'</span>
|
|
<span class="sd"> argument is true, exactly one entry appears in the returned structure</span>
|
|
<span class="sd"> for each class in the given list. Otherwise, classes using multiple</span>
|
|
<span class="sd"> inheritance and their descendants will appear multiple times."""</span>
|
|
<span class="n">children</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">roots</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">classes</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">c</span><span class="o">.</span><span class="vm">__bases__</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">parent</span> <span class="ow">in</span> <span class="n">c</span><span class="o">.</span><span class="vm">__bases__</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">parent</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">children</span><span class="p">:</span>
|
|
<span class="n">children</span><span class="p">[</span><span class="n">parent</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">c</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">children</span><span class="p">[</span><span class="n">parent</span><span class="p">]:</span>
|
|
<span class="n">children</span><span class="p">[</span><span class="n">parent</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">unique</span> <span class="ow">and</span> <span class="n">parent</span> <span class="ow">in</span> <span class="n">classes</span><span class="p">:</span> <span class="k">break</span>
|
|
<span class="k">elif</span> <span class="n">c</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">roots</span><span class="p">:</span>
|
|
<span class="n">roots</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">parent</span> <span class="ow">in</span> <span class="n">children</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">parent</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">classes</span><span class="p">:</span>
|
|
<span class="n">roots</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">parent</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">walktree</span><span class="p">(</span><span class="n">roots</span><span class="p">,</span> <span class="n">children</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
|
|
<span class="c1"># ------------------------------------------------ argument list extraction</span>
|
|
<span class="n">Arguments</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'Arguments'</span><span class="p">,</span> <span class="s1">'args, varargs, varkw'</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getargs</span><span class="p">(</span><span class="n">co</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get information about the arguments accepted by a code object.</span>
|
|
|
|
<span class="sd"> Three things are returned: (args, varargs, varkw), where</span>
|
|
<span class="sd"> 'args' is the list of argument names. Keyword-only arguments are</span>
|
|
<span class="sd"> appended. 'varargs' and 'varkw' are the names of the * and **</span>
|
|
<span class="sd"> arguments or None."""</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">iscode</span><span class="p">(</span><span class="n">co</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'</span><span class="si">{!r}</span><span class="s1"> is not a code object'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">co</span><span class="p">))</span>
|
|
|
|
<span class="n">names</span> <span class="o">=</span> <span class="n">co</span><span class="o">.</span><span class="n">co_varnames</span>
|
|
<span class="n">nargs</span> <span class="o">=</span> <span class="n">co</span><span class="o">.</span><span class="n">co_argcount</span>
|
|
<span class="n">nkwargs</span> <span class="o">=</span> <span class="n">co</span><span class="o">.</span><span class="n">co_kwonlyargcount</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">names</span><span class="p">[:</span><span class="n">nargs</span><span class="p">])</span>
|
|
<span class="n">kwonlyargs</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">names</span><span class="p">[</span><span class="n">nargs</span><span class="p">:</span><span class="n">nargs</span><span class="o">+</span><span class="n">nkwargs</span><span class="p">])</span>
|
|
|
|
<span class="n">nargs</span> <span class="o">+=</span> <span class="n">nkwargs</span>
|
|
<span class="n">varargs</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="n">co</span><span class="o">.</span><span class="n">co_flags</span> <span class="o">&</span> <span class="n">CO_VARARGS</span><span class="p">:</span>
|
|
<span class="n">varargs</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">nargs</span><span class="p">]</span>
|
|
<span class="n">nargs</span> <span class="o">=</span> <span class="n">nargs</span> <span class="o">+</span> <span class="mi">1</span>
|
|
<span class="n">varkw</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="n">co</span><span class="o">.</span><span class="n">co_flags</span> <span class="o">&</span> <span class="n">CO_VARKEYWORDS</span><span class="p">:</span>
|
|
<span class="n">varkw</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">nargs</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="n">Arguments</span><span class="p">(</span><span class="n">args</span> <span class="o">+</span> <span class="n">kwonlyargs</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="p">)</span>
|
|
|
|
|
|
<span class="n">FullArgSpec</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'FullArgSpec'</span><span class="p">,</span>
|
|
<span class="s1">'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations'</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getfullargspec</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get the names and default values of a callable object's parameters.</span>
|
|
|
|
<span class="sd"> A tuple of seven things is returned:</span>
|
|
<span class="sd"> (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations).</span>
|
|
<span class="sd"> 'args' is a list of the parameter names.</span>
|
|
<span class="sd"> 'varargs' and 'varkw' are the names of the * and ** parameters or None.</span>
|
|
<span class="sd"> 'defaults' is an n-tuple of the default values of the last n parameters.</span>
|
|
<span class="sd"> 'kwonlyargs' is a list of keyword-only parameter names.</span>
|
|
<span class="sd"> 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.</span>
|
|
<span class="sd"> 'annotations' is a dictionary mapping parameter names to annotations.</span>
|
|
|
|
<span class="sd"> Notable differences from inspect.signature():</span>
|
|
<span class="sd"> - the "self" parameter is always reported, even for bound methods</span>
|
|
<span class="sd"> - wrapper chains defined by __wrapped__ *not* unwrapped automatically</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># Re: `skip_bound_arg=False`</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># There is a notable difference in behaviour between getfullargspec</span>
|
|
<span class="c1"># and Signature: the former always returns 'self' parameter for bound</span>
|
|
<span class="c1"># methods, whereas the Signature always shows the actual calling</span>
|
|
<span class="c1"># signature of the passed object.</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># To simulate this behaviour, we "unbind" bound methods, to trick</span>
|
|
<span class="c1"># inspect.signature to always return their first parameter ("self",</span>
|
|
<span class="c1"># usually)</span>
|
|
|
|
<span class="c1"># Re: `follow_wrapper_chains=False`</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># getfullargspec() historically ignored __wrapped__ attributes,</span>
|
|
<span class="c1"># so we ensure that remains the case in 3.3+</span>
|
|
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="n">_signature_from_callable</span><span class="p">(</span><span class="n">func</span><span class="p">,</span>
|
|
<span class="n">follow_wrapper_chains</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
|
<span class="n">skip_bound_arg</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
|
<span class="n">sigcls</span><span class="o">=</span><span class="n">Signature</span><span class="p">,</span>
|
|
<span class="n">eval_str</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
|
|
<span class="c1"># Most of the times 'signature' will raise ValueError.</span>
|
|
<span class="c1"># But, it can also raise AttributeError, and, maybe something</span>
|
|
<span class="c1"># else. So to be fully backwards compatible, we catch all</span>
|
|
<span class="c1"># possible exceptions here, and reraise a TypeError.</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'unsupported callable'</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">ex</span>
|
|
|
|
<span class="n">args</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">varargs</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">varkw</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">posonlyargs</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">kwonlyargs</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">annotations</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">defaults</span> <span class="o">=</span> <span class="p">()</span>
|
|
<span class="n">kwdefaults</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="k">if</span> <span class="n">sig</span><span class="o">.</span><span class="n">return_annotation</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">sig</span><span class="o">.</span><span class="n">empty</span><span class="p">:</span>
|
|
<span class="n">annotations</span><span class="p">[</span><span class="s1">'return'</span><span class="p">]</span> <span class="o">=</span> <span class="n">sig</span><span class="o">.</span><span class="n">return_annotation</span>
|
|
|
|
<span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">sig</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="n">name</span>
|
|
|
|
<span class="k">if</span> <span class="n">kind</span> <span class="ow">is</span> <span class="n">_POSITIONAL_ONLY</span><span class="p">:</span>
|
|
<span class="n">posonlyargs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">default</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">param</span><span class="o">.</span><span class="n">empty</span><span class="p">:</span>
|
|
<span class="n">defaults</span> <span class="o">+=</span> <span class="p">(</span><span class="n">param</span><span class="o">.</span><span class="n">default</span><span class="p">,)</span>
|
|
<span class="k">elif</span> <span class="n">kind</span> <span class="ow">is</span> <span class="n">_POSITIONAL_OR_KEYWORD</span><span class="p">:</span>
|
|
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">default</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">param</span><span class="o">.</span><span class="n">empty</span><span class="p">:</span>
|
|
<span class="n">defaults</span> <span class="o">+=</span> <span class="p">(</span><span class="n">param</span><span class="o">.</span><span class="n">default</span><span class="p">,)</span>
|
|
<span class="k">elif</span> <span class="n">kind</span> <span class="ow">is</span> <span class="n">_VAR_POSITIONAL</span><span class="p">:</span>
|
|
<span class="n">varargs</span> <span class="o">=</span> <span class="n">name</span>
|
|
<span class="k">elif</span> <span class="n">kind</span> <span class="ow">is</span> <span class="n">_KEYWORD_ONLY</span><span class="p">:</span>
|
|
<span class="n">kwonlyargs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">default</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">param</span><span class="o">.</span><span class="n">empty</span><span class="p">:</span>
|
|
<span class="n">kwdefaults</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="n">default</span>
|
|
<span class="k">elif</span> <span class="n">kind</span> <span class="ow">is</span> <span class="n">_VAR_KEYWORD</span><span class="p">:</span>
|
|
<span class="n">varkw</span> <span class="o">=</span> <span class="n">name</span>
|
|
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">annotation</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">param</span><span class="o">.</span><span class="n">empty</span><span class="p">:</span>
|
|
<span class="n">annotations</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="n">annotation</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">kwdefaults</span><span class="p">:</span>
|
|
<span class="c1"># compatibility with 'func.__kwdefaults__'</span>
|
|
<span class="n">kwdefaults</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">defaults</span><span class="p">:</span>
|
|
<span class="c1"># compatibility with 'func.__defaults__'</span>
|
|
<span class="n">defaults</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="k">return</span> <span class="n">FullArgSpec</span><span class="p">(</span><span class="n">posonlyargs</span> <span class="o">+</span> <span class="n">args</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="p">,</span> <span class="n">defaults</span><span class="p">,</span>
|
|
<span class="n">kwonlyargs</span><span class="p">,</span> <span class="n">kwdefaults</span><span class="p">,</span> <span class="n">annotations</span><span class="p">)</span>
|
|
|
|
|
|
<span class="n">ArgInfo</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'ArgInfo'</span><span class="p">,</span> <span class="s1">'args varargs keywords locals'</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getargvalues</span><span class="p">(</span><span class="n">frame</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get information about arguments passed into a particular frame.</span>
|
|
|
|
<span class="sd"> A tuple of four things is returned: (args, varargs, varkw, locals).</span>
|
|
<span class="sd"> 'args' is a list of the argument names.</span>
|
|
<span class="sd"> 'varargs' and 'varkw' are the names of the * and ** arguments or None.</span>
|
|
<span class="sd"> 'locals' is the locals dictionary of the given frame."""</span>
|
|
<span class="n">args</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span> <span class="o">=</span> <span class="n">getargs</span><span class="p">(</span><span class="n">frame</span><span class="o">.</span><span class="n">f_code</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">ArgInfo</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="p">,</span> <span class="n">frame</span><span class="o">.</span><span class="n">f_locals</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">formatannotation</span><span class="p">(</span><span class="n">annotation</span><span class="p">,</span> <span class="n">base_module</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">annotation</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="o">==</span> <span class="s1">'typing'</span><span class="p">:</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">repl</span><span class="p">(</span><span class="n">match</span><span class="p">):</span>
|
|
<span class="n">text</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="n">text</span><span class="o">.</span><span class="n">removeprefix</span><span class="p">(</span><span class="s1">'typing.'</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s1">'[\w\.]+'</span><span class="p">,</span> <span class="n">repl</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">annotation</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">annotation</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">GenericAlias</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">annotation</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">annotation</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">annotation</span><span class="o">.</span><span class="vm">__module__</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'builtins'</span><span class="p">,</span> <span class="n">base_module</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">annotation</span><span class="o">.</span><span class="vm">__qualname__</span>
|
|
<span class="k">return</span> <span class="n">annotation</span><span class="o">.</span><span class="vm">__module__</span><span class="o">+</span><span class="s1">'.'</span><span class="o">+</span><span class="n">annotation</span><span class="o">.</span><span class="vm">__qualname__</span>
|
|
<span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="n">annotation</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">formatannotationrelativeto</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="n">module</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_formatannotation</span><span class="p">(</span><span class="n">annotation</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">formatannotation</span><span class="p">(</span><span class="n">annotation</span><span class="p">,</span> <span class="n">module</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_formatannotation</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">formatargvalues</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="p">,</span> <span class="nb">locals</span><span class="p">,</span>
|
|
<span class="n">formatarg</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span>
|
|
<span class="n">formatvarargs</span><span class="o">=</span><span class="k">lambda</span> <span class="n">name</span><span class="p">:</span> <span class="s1">'*'</span> <span class="o">+</span> <span class="n">name</span><span class="p">,</span>
|
|
<span class="n">formatvarkw</span><span class="o">=</span><span class="k">lambda</span> <span class="n">name</span><span class="p">:</span> <span class="s1">'**'</span> <span class="o">+</span> <span class="n">name</span><span class="p">,</span>
|
|
<span class="n">formatvalue</span><span class="o">=</span><span class="k">lambda</span> <span class="n">value</span><span class="p">:</span> <span class="s1">'='</span> <span class="o">+</span> <span class="nb">repr</span><span class="p">(</span><span class="n">value</span><span class="p">)):</span>
|
|
<span class="w"> </span><span class="sd">"""Format an argument spec from the 4 values returned by getargvalues.</span>
|
|
|
|
<span class="sd"> The first four arguments are (args, varargs, varkw, locals). The</span>
|
|
<span class="sd"> next four arguments are the corresponding optional formatting functions</span>
|
|
<span class="sd"> that are called to turn names and values into strings. The ninth</span>
|
|
<span class="sd"> argument is an optional function to format the sequence of arguments."""</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">convert</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="nb">locals</span><span class="o">=</span><span class="nb">locals</span><span class="p">,</span>
|
|
<span class="n">formatarg</span><span class="o">=</span><span class="n">formatarg</span><span class="p">,</span> <span class="n">formatvalue</span><span class="o">=</span><span class="n">formatvalue</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">formatarg</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">+</span> <span class="n">formatvalue</span><span class="p">(</span><span class="nb">locals</span><span class="p">[</span><span class="n">name</span><span class="p">])</span>
|
|
<span class="n">specs</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)):</span>
|
|
<span class="n">specs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">convert</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span>
|
|
<span class="k">if</span> <span class="n">varargs</span><span class="p">:</span>
|
|
<span class="n">specs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">formatvarargs</span><span class="p">(</span><span class="n">varargs</span><span class="p">)</span> <span class="o">+</span> <span class="n">formatvalue</span><span class="p">(</span><span class="nb">locals</span><span class="p">[</span><span class="n">varargs</span><span class="p">]))</span>
|
|
<span class="k">if</span> <span class="n">varkw</span><span class="p">:</span>
|
|
<span class="n">specs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">formatvarkw</span><span class="p">(</span><span class="n">varkw</span><span class="p">)</span> <span class="o">+</span> <span class="n">formatvalue</span><span class="p">(</span><span class="nb">locals</span><span class="p">[</span><span class="n">varkw</span><span class="p">]))</span>
|
|
<span class="k">return</span> <span class="s1">'('</span> <span class="o">+</span> <span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">specs</span><span class="p">)</span> <span class="o">+</span> <span class="s1">')'</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_missing_arguments</span><span class="p">(</span><span class="n">f_name</span><span class="p">,</span> <span class="n">argnames</span><span class="p">,</span> <span class="n">pos</span><span class="p">,</span> <span class="n">values</span><span class="p">):</span>
|
|
<span class="n">names</span> <span class="o">=</span> <span class="p">[</span><span class="nb">repr</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">argnames</span> <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">values</span><span class="p">]</span>
|
|
<span class="n">missing</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">names</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">missing</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="n">s</span> <span class="o">=</span> <span class="n">names</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">missing</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
|
|
<span class="n">s</span> <span class="o">=</span> <span class="s2">"</span><span class="si">{}</span><span class="s2"> and </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">*</span><span class="n">names</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">tail</span> <span class="o">=</span> <span class="s2">", </span><span class="si">{}</span><span class="s2"> and </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">*</span><span class="n">names</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">:])</span>
|
|
<span class="k">del</span> <span class="n">names</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">:]</span>
|
|
<span class="n">s</span> <span class="o">=</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">names</span><span class="p">)</span> <span class="o">+</span> <span class="n">tail</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"</span><span class="si">%s</span><span class="s2">() missing </span><span class="si">%i</span><span class="s2"> required </span><span class="si">%s</span><span class="s2"> argument</span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span>
|
|
<span class="p">(</span><span class="n">f_name</span><span class="p">,</span> <span class="n">missing</span><span class="p">,</span>
|
|
<span class="s2">"positional"</span> <span class="k">if</span> <span class="n">pos</span> <span class="k">else</span> <span class="s2">"keyword-only"</span><span class="p">,</span>
|
|
<span class="s2">""</span> <span class="k">if</span> <span class="n">missing</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">else</span> <span class="s2">"s"</span><span class="p">,</span> <span class="n">s</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_too_many</span><span class="p">(</span><span class="n">f_name</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwonly</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">defcount</span><span class="p">,</span> <span class="n">given</span><span class="p">,</span> <span class="n">values</span><span class="p">):</span>
|
|
<span class="n">atleast</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">-</span> <span class="n">defcount</span>
|
|
<span class="n">kwonly_given</span> <span class="o">=</span> <span class="nb">len</span><span class="p">([</span><span class="n">arg</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">kwonly</span> <span class="k">if</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">values</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="n">varargs</span><span class="p">:</span>
|
|
<span class="n">plural</span> <span class="o">=</span> <span class="n">atleast</span> <span class="o">!=</span> <span class="mi">1</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="s2">"at least </span><span class="si">%d</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">atleast</span><span class="p">,)</span>
|
|
<span class="k">elif</span> <span class="n">defcount</span><span class="p">:</span>
|
|
<span class="n">plural</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="s2">"from </span><span class="si">%d</span><span class="s2"> to </span><span class="si">%d</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">atleast</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">))</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">plural</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">))</span>
|
|
<span class="n">kwonly_sig</span> <span class="o">=</span> <span class="s2">""</span>
|
|
<span class="k">if</span> <span class="n">kwonly_given</span><span class="p">:</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s2">" positional argument</span><span class="si">%s</span><span class="s2"> (and </span><span class="si">%d</span><span class="s2"> keyword-only argument</span><span class="si">%s</span><span class="s2">)"</span>
|
|
<span class="n">kwonly_sig</span> <span class="o">=</span> <span class="p">(</span><span class="n">msg</span> <span class="o">%</span> <span class="p">(</span><span class="s2">"s"</span> <span class="k">if</span> <span class="n">given</span> <span class="o">!=</span> <span class="mi">1</span> <span class="k">else</span> <span class="s2">""</span><span class="p">,</span> <span class="n">kwonly_given</span><span class="p">,</span>
|
|
<span class="s2">"s"</span> <span class="k">if</span> <span class="n">kwonly_given</span> <span class="o">!=</span> <span class="mi">1</span> <span class="k">else</span> <span class="s2">""</span><span class="p">))</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"</span><span class="si">%s</span><span class="s2">() takes </span><span class="si">%s</span><span class="s2"> positional argument</span><span class="si">%s</span><span class="s2"> but </span><span class="si">%d%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2"> given"</span> <span class="o">%</span>
|
|
<span class="p">(</span><span class="n">f_name</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="s2">"s"</span> <span class="k">if</span> <span class="n">plural</span> <span class="k">else</span> <span class="s2">""</span><span class="p">,</span> <span class="n">given</span><span class="p">,</span> <span class="n">kwonly_sig</span><span class="p">,</span>
|
|
<span class="s2">"was"</span> <span class="k">if</span> <span class="n">given</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">kwonly_given</span> <span class="k">else</span> <span class="s2">"were"</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getcallargs</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">*</span><span class="n">positional</span><span class="p">,</span> <span class="o">**</span><span class="n">named</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get the mapping of arguments to values.</span>
|
|
|
|
<span class="sd"> A dict is returned, with keys the function argument names (including the</span>
|
|
<span class="sd"> names of the * and ** arguments, if any), and values the respective bound</span>
|
|
<span class="sd"> values from 'positional' and 'named'."""</span>
|
|
<span class="n">spec</span> <span class="o">=</span> <span class="n">getfullargspec</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>
|
|
<span class="n">args</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">varkw</span><span class="p">,</span> <span class="n">defaults</span><span class="p">,</span> <span class="n">kwonlyargs</span><span class="p">,</span> <span class="n">kwonlydefaults</span><span class="p">,</span> <span class="n">ann</span> <span class="o">=</span> <span class="n">spec</span>
|
|
<span class="n">f_name</span> <span class="o">=</span> <span class="n">func</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="n">arg2value</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
|
|
<span class="k">if</span> <span class="n">ismethod</span><span class="p">(</span><span class="n">func</span><span class="p">)</span> <span class="ow">and</span> <span class="n">func</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="c1"># implicit 'self' (or 'cls' for classmethods) argument</span>
|
|
<span class="n">positional</span> <span class="o">=</span> <span class="p">(</span><span class="n">func</span><span class="o">.</span><span class="vm">__self__</span><span class="p">,)</span> <span class="o">+</span> <span class="n">positional</span>
|
|
<span class="n">num_pos</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">positional</span><span class="p">)</span>
|
|
<span class="n">num_args</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
|
|
<span class="n">num_defaults</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">defaults</span><span class="p">)</span> <span class="k">if</span> <span class="n">defaults</span> <span class="k">else</span> <span class="mi">0</span>
|
|
|
|
<span class="n">n</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">num_pos</span><span class="p">,</span> <span class="n">num_args</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
|
|
<span class="n">arg2value</span><span class="p">[</span><span class="n">args</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span> <span class="o">=</span> <span class="n">positional</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">varargs</span><span class="p">:</span>
|
|
<span class="n">arg2value</span><span class="p">[</span><span class="n">varargs</span><span class="p">]</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">positional</span><span class="p">[</span><span class="n">n</span><span class="p">:])</span>
|
|
<span class="n">possible_kwargs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">args</span> <span class="o">+</span> <span class="n">kwonlyargs</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">varkw</span><span class="p">:</span>
|
|
<span class="n">arg2value</span><span class="p">[</span><span class="n">varkw</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">for</span> <span class="n">kw</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">named</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">kw</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">possible_kwargs</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">varkw</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"</span><span class="si">%s</span><span class="s2">() got an unexpected keyword argument </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span>
|
|
<span class="p">(</span><span class="n">f_name</span><span class="p">,</span> <span class="n">kw</span><span class="p">))</span>
|
|
<span class="n">arg2value</span><span class="p">[</span><span class="n">varkw</span><span class="p">][</span><span class="n">kw</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">if</span> <span class="n">kw</span> <span class="ow">in</span> <span class="n">arg2value</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"</span><span class="si">%s</span><span class="s2">() got multiple values for argument </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span>
|
|
<span class="p">(</span><span class="n">f_name</span><span class="p">,</span> <span class="n">kw</span><span class="p">))</span>
|
|
<span class="n">arg2value</span><span class="p">[</span><span class="n">kw</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="k">if</span> <span class="n">num_pos</span> <span class="o">></span> <span class="n">num_args</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">varargs</span><span class="p">:</span>
|
|
<span class="n">_too_many</span><span class="p">(</span><span class="n">f_name</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwonlyargs</span><span class="p">,</span> <span class="n">varargs</span><span class="p">,</span> <span class="n">num_defaults</span><span class="p">,</span>
|
|
<span class="n">num_pos</span><span class="p">,</span> <span class="n">arg2value</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">num_pos</span> <span class="o"><</span> <span class="n">num_args</span><span class="p">:</span>
|
|
<span class="n">req</span> <span class="o">=</span> <span class="n">args</span><span class="p">[:</span><span class="n">num_args</span> <span class="o">-</span> <span class="n">num_defaults</span><span class="p">]</span>
|
|
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">req</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">arg</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">arg2value</span><span class="p">:</span>
|
|
<span class="n">_missing_arguments</span><span class="p">(</span><span class="n">f_name</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="kc">True</span><span class="p">,</span> <span class="n">arg2value</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">arg</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="n">num_args</span> <span class="o">-</span> <span class="n">num_defaults</span><span class="p">:]):</span>
|
|
<span class="k">if</span> <span class="n">arg</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">arg2value</span><span class="p">:</span>
|
|
<span class="n">arg2value</span><span class="p">[</span><span class="n">arg</span><span class="p">]</span> <span class="o">=</span> <span class="n">defaults</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
|
|
<span class="n">missing</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="k">for</span> <span class="n">kwarg</span> <span class="ow">in</span> <span class="n">kwonlyargs</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">kwarg</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">arg2value</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">kwonlydefaults</span> <span class="ow">and</span> <span class="n">kwarg</span> <span class="ow">in</span> <span class="n">kwonlydefaults</span><span class="p">:</span>
|
|
<span class="n">arg2value</span><span class="p">[</span><span class="n">kwarg</span><span class="p">]</span> <span class="o">=</span> <span class="n">kwonlydefaults</span><span class="p">[</span><span class="n">kwarg</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">missing</span> <span class="o">+=</span> <span class="mi">1</span>
|
|
<span class="k">if</span> <span class="n">missing</span><span class="p">:</span>
|
|
<span class="n">_missing_arguments</span><span class="p">(</span><span class="n">f_name</span><span class="p">,</span> <span class="n">kwonlyargs</span><span class="p">,</span> <span class="kc">False</span><span class="p">,</span> <span class="n">arg2value</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">arg2value</span>
|
|
|
|
<span class="n">ClosureVars</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'ClosureVars'</span><span class="p">,</span> <span class="s1">'nonlocals globals builtins unbound'</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getclosurevars</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Get the mapping of free variables to their current values.</span>
|
|
|
|
<span class="sd"> Returns a named tuple of dicts mapping the current nonlocal, global</span>
|
|
<span class="sd"> and builtin references as seen by the body of the function. A final</span>
|
|
<span class="sd"> set of unbound names that could not be resolved is also provided.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">if</span> <span class="n">ismethod</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="n">func</span> <span class="o">=</span> <span class="n">func</span><span class="o">.</span><span class="vm">__func__</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">isfunction</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"</span><span class="si">{!r}</span><span class="s2"> is not a Python function"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">func</span><span class="p">))</span>
|
|
|
|
<span class="n">code</span> <span class="o">=</span> <span class="n">func</span><span class="o">.</span><span class="vm">__code__</span>
|
|
<span class="c1"># Nonlocal references are named in co_freevars and resolved</span>
|
|
<span class="c1"># by looking them up in __closure__ by positional index</span>
|
|
<span class="k">if</span> <span class="n">func</span><span class="o">.</span><span class="vm">__closure__</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">nonlocal_vars</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">nonlocal_vars</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="n">var</span> <span class="p">:</span> <span class="n">cell</span><span class="o">.</span><span class="n">cell_contents</span>
|
|
<span class="k">for</span> <span class="n">var</span><span class="p">,</span> <span class="n">cell</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">code</span><span class="o">.</span><span class="n">co_freevars</span><span class="p">,</span> <span class="n">func</span><span class="o">.</span><span class="vm">__closure__</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="c1"># Global and builtin references are named in co_names and resolved</span>
|
|
<span class="c1"># by looking them up in __globals__ or __builtins__</span>
|
|
<span class="n">global_ns</span> <span class="o">=</span> <span class="n">func</span><span class="o">.</span><span class="vm">__globals__</span>
|
|
<span class="n">builtin_ns</span> <span class="o">=</span> <span class="n">global_ns</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"__builtins__"</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="k">if</span> <span class="n">ismodule</span><span class="p">(</span><span class="n">builtin_ns</span><span class="p">):</span>
|
|
<span class="n">builtin_ns</span> <span class="o">=</span> <span class="n">builtin_ns</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="n">global_vars</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">builtin_vars</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">unbound_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="n">global_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">instruction</span> <span class="ow">in</span> <span class="n">dis</span><span class="o">.</span><span class="n">get_instructions</span><span class="p">(</span><span class="n">code</span><span class="p">):</span>
|
|
<span class="n">opname</span> <span class="o">=</span> <span class="n">instruction</span><span class="o">.</span><span class="n">opname</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">instruction</span><span class="o">.</span><span class="n">argval</span>
|
|
<span class="k">if</span> <span class="n">opname</span> <span class="o">==</span> <span class="s2">"LOAD_ATTR"</span><span class="p">:</span>
|
|
<span class="n">unbound_names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">opname</span> <span class="o">==</span> <span class="s2">"LOAD_GLOBAL"</span><span class="p">:</span>
|
|
<span class="n">global_names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">global_names</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">global_vars</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">global_ns</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">builtin_vars</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">builtin_ns</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="n">unbound_names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">ClosureVars</span><span class="p">(</span><span class="n">nonlocal_vars</span><span class="p">,</span> <span class="n">global_vars</span><span class="p">,</span>
|
|
<span class="n">builtin_vars</span><span class="p">,</span> <span class="n">unbound_names</span><span class="p">)</span>
|
|
|
|
<span class="c1"># -------------------------------------------------- stack frame extraction</span>
|
|
|
|
<span class="n">_Traceback</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'_Traceback'</span><span class="p">,</span> <span class="s1">'filename lineno function code_context index'</span><span class="p">)</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">Traceback</span><span class="p">(</span><span class="n">_Traceback</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">function</span><span class="p">,</span> <span class="n">code_context</span><span class="p">,</span> <span class="n">index</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">positions</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="n">instance</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">function</span><span class="p">,</span> <span class="n">code_context</span><span class="p">,</span> <span class="n">index</span><span class="p">)</span>
|
|
<span class="n">instance</span><span class="o">.</span><span class="n">positions</span> <span class="o">=</span> <span class="n">positions</span>
|
|
<span class="k">return</span> <span class="n">instance</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="s1">'Traceback(filename=</span><span class="si">{!r}</span><span class="s1">, lineno=</span><span class="si">{!r}</span><span class="s1">, function=</span><span class="si">{!r}</span><span class="s1">, '</span>
|
|
<span class="s1">'code_context=</span><span class="si">{!r}</span><span class="s1">, index=</span><span class="si">{!r}</span><span class="s1">, positions=</span><span class="si">{!r}</span><span class="s1">)'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">lineno</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">function</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">code_context</span><span class="p">,</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">index</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">positions</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_get_code_position_from_tb</span><span class="p">(</span><span class="n">tb</span><span class="p">):</span>
|
|
<span class="n">code</span><span class="p">,</span> <span class="n">instruction_index</span> <span class="o">=</span> <span class="n">tb</span><span class="o">.</span><span class="n">tb_frame</span><span class="o">.</span><span class="n">f_code</span><span class="p">,</span> <span class="n">tb</span><span class="o">.</span><span class="n">tb_lasti</span>
|
|
<span class="k">return</span> <span class="n">_get_code_position</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">instruction_index</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_get_code_position</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">instruction_index</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">instruction_index</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">positions_gen</span> <span class="o">=</span> <span class="n">code</span><span class="o">.</span><span class="n">co_positions</span><span class="p">()</span>
|
|
<span class="c1"># The nth entry in code.co_positions() corresponds to instruction (2*n)th since Python 3.10+</span>
|
|
<span class="k">return</span> <span class="nb">next</span><span class="p">(</span><span class="n">itertools</span><span class="o">.</span><span class="n">islice</span><span class="p">(</span><span class="n">positions_gen</span><span class="p">,</span> <span class="n">instruction_index</span> <span class="o">//</span> <span class="mi">2</span><span class="p">,</span> <span class="kc">None</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getframeinfo</span><span class="p">(</span><span class="n">frame</span><span class="p">,</span> <span class="n">context</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get information about a frame or traceback object.</span>
|
|
|
|
<span class="sd"> A tuple of five things is returned: the filename, the line number of</span>
|
|
<span class="sd"> the current line, the function name, a list of lines of context from</span>
|
|
<span class="sd"> the source code, and the index of the current line within that list.</span>
|
|
<span class="sd"> The optional second argument specifies the number of lines of context</span>
|
|
<span class="sd"> to return, which are centered around the current line."""</span>
|
|
<span class="k">if</span> <span class="n">istraceback</span><span class="p">(</span><span class="n">frame</span><span class="p">):</span>
|
|
<span class="n">positions</span> <span class="o">=</span> <span class="n">_get_code_position_from_tb</span><span class="p">(</span><span class="n">frame</span><span class="p">)</span>
|
|
<span class="n">lineno</span> <span class="o">=</span> <span class="n">frame</span><span class="o">.</span><span class="n">tb_lineno</span>
|
|
<span class="n">frame</span> <span class="o">=</span> <span class="n">frame</span><span class="o">.</span><span class="n">tb_frame</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">lineno</span> <span class="o">=</span> <span class="n">frame</span><span class="o">.</span><span class="n">f_lineno</span>
|
|
<span class="n">positions</span> <span class="o">=</span> <span class="n">_get_code_position</span><span class="p">(</span><span class="n">frame</span><span class="o">.</span><span class="n">f_code</span><span class="p">,</span> <span class="n">frame</span><span class="o">.</span><span class="n">f_lasti</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">positions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">frame</span><span class="p">,</span> <span class="o">*</span><span class="n">positions</span> <span class="o">=</span> <span class="p">(</span><span class="n">frame</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="o">*</span><span class="n">positions</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">frame</span><span class="p">,</span> <span class="o">*</span><span class="n">positions</span> <span class="o">=</span> <span class="p">(</span><span class="n">frame</span><span class="p">,</span> <span class="o">*</span><span class="n">positions</span><span class="p">)</span>
|
|
|
|
<span class="n">lineno</span> <span class="o">=</span> <span class="n">positions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">isframe</span><span class="p">(</span><span class="n">frame</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'</span><span class="si">{!r}</span><span class="s1"> is not a frame or traceback object'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">frame</span><span class="p">))</span>
|
|
|
|
<span class="n">filename</span> <span class="o">=</span> <span class="n">getsourcefile</span><span class="p">(</span><span class="n">frame</span><span class="p">)</span> <span class="ow">or</span> <span class="n">getfile</span><span class="p">(</span><span class="n">frame</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">context</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="n">start</span> <span class="o">=</span> <span class="n">lineno</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">context</span><span class="o">//</span><span class="mi">2</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">lines</span><span class="p">,</span> <span class="n">lnum</span> <span class="o">=</span> <span class="n">findsource</span><span class="p">(</span><span class="n">frame</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
|
|
<span class="n">lines</span> <span class="o">=</span> <span class="n">index</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">start</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">min</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span> <span class="o">-</span> <span class="n">context</span><span class="p">))</span>
|
|
<span class="n">lines</span> <span class="o">=</span> <span class="n">lines</span><span class="p">[</span><span class="n">start</span><span class="p">:</span><span class="n">start</span><span class="o">+</span><span class="n">context</span><span class="p">]</span>
|
|
<span class="n">index</span> <span class="o">=</span> <span class="n">lineno</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">start</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">lines</span> <span class="o">=</span> <span class="n">index</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="k">return</span> <span class="n">Traceback</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">frame</span><span class="o">.</span><span class="n">f_code</span><span class="o">.</span><span class="n">co_name</span><span class="p">,</span> <span class="n">lines</span><span class="p">,</span>
|
|
<span class="n">index</span><span class="p">,</span> <span class="n">positions</span><span class="o">=</span><span class="n">dis</span><span class="o">.</span><span class="n">Positions</span><span class="p">(</span><span class="o">*</span><span class="n">positions</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getlineno</span><span class="p">(</span><span class="n">frame</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get the line number from a frame object, allowing for optimization."""</span>
|
|
<span class="c1"># FrameType.f_lineno is now a descriptor that grovels co_lnotab</span>
|
|
<span class="k">return</span> <span class="n">frame</span><span class="o">.</span><span class="n">f_lineno</span>
|
|
|
|
<span class="n">_FrameInfo</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'_FrameInfo'</span><span class="p">,</span> <span class="p">(</span><span class="s1">'frame'</span><span class="p">,)</span> <span class="o">+</span> <span class="n">Traceback</span><span class="o">.</span><span class="n">_fields</span><span class="p">)</span>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">FrameInfo</span><span class="p">(</span><span class="n">_FrameInfo</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">frame</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">function</span><span class="p">,</span> <span class="n">code_context</span><span class="p">,</span> <span class="n">index</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">positions</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="n">instance</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">frame</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">function</span><span class="p">,</span> <span class="n">code_context</span><span class="p">,</span> <span class="n">index</span><span class="p">)</span>
|
|
<span class="n">instance</span><span class="o">.</span><span class="n">positions</span> <span class="o">=</span> <span class="n">positions</span>
|
|
<span class="k">return</span> <span class="n">instance</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="s1">'FrameInfo(frame=</span><span class="si">{!r}</span><span class="s1">, filename=</span><span class="si">{!r}</span><span class="s1">, lineno=</span><span class="si">{!r}</span><span class="s1">, function=</span><span class="si">{!r}</span><span class="s1">, '</span>
|
|
<span class="s1">'code_context=</span><span class="si">{!r}</span><span class="s1">, index=</span><span class="si">{!r}</span><span class="s1">, positions=</span><span class="si">{!r}</span><span class="s1">)'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">frame</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">lineno</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">function</span><span class="p">,</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">code_context</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">index</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">positions</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getouterframes</span><span class="p">(</span><span class="n">frame</span><span class="p">,</span> <span class="n">context</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get a list of records for a frame and all higher (calling) frames.</span>
|
|
|
|
<span class="sd"> Each record contains a frame object, filename, line number, function</span>
|
|
<span class="sd"> name, a list of lines of context, and index within the context."""</span>
|
|
<span class="n">framelist</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">while</span> <span class="n">frame</span><span class="p">:</span>
|
|
<span class="n">traceback_info</span> <span class="o">=</span> <span class="n">getframeinfo</span><span class="p">(</span><span class="n">frame</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
|
|
<span class="n">frameinfo</span> <span class="o">=</span> <span class="p">(</span><span class="n">frame</span><span class="p">,)</span> <span class="o">+</span> <span class="n">traceback_info</span>
|
|
<span class="n">framelist</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">FrameInfo</span><span class="p">(</span><span class="o">*</span><span class="n">frameinfo</span><span class="p">,</span> <span class="n">positions</span><span class="o">=</span><span class="n">traceback_info</span><span class="o">.</span><span class="n">positions</span><span class="p">))</span>
|
|
<span class="n">frame</span> <span class="o">=</span> <span class="n">frame</span><span class="o">.</span><span class="n">f_back</span>
|
|
<span class="k">return</span> <span class="n">framelist</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getinnerframes</span><span class="p">(</span><span class="n">tb</span><span class="p">,</span> <span class="n">context</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get a list of records for a traceback's frame and all lower frames.</span>
|
|
|
|
<span class="sd"> Each record contains a frame object, filename, line number, function</span>
|
|
<span class="sd"> name, a list of lines of context, and index within the context."""</span>
|
|
<span class="n">framelist</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">while</span> <span class="n">tb</span><span class="p">:</span>
|
|
<span class="n">traceback_info</span> <span class="o">=</span> <span class="n">getframeinfo</span><span class="p">(</span><span class="n">tb</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
|
|
<span class="n">frameinfo</span> <span class="o">=</span> <span class="p">(</span><span class="n">tb</span><span class="o">.</span><span class="n">tb_frame</span><span class="p">,)</span> <span class="o">+</span> <span class="n">traceback_info</span>
|
|
<span class="n">framelist</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">FrameInfo</span><span class="p">(</span><span class="o">*</span><span class="n">frameinfo</span><span class="p">,</span> <span class="n">positions</span><span class="o">=</span><span class="n">traceback_info</span><span class="o">.</span><span class="n">positions</span><span class="p">))</span>
|
|
<span class="n">tb</span> <span class="o">=</span> <span class="n">tb</span><span class="o">.</span><span class="n">tb_next</span>
|
|
<span class="k">return</span> <span class="n">framelist</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">currentframe</span><span class="p">():</span>
|
|
<span class="w"> </span><span class="sd">"""Return the frame of the caller or None if this is not possible."""</span>
|
|
<span class="k">return</span> <span class="n">sys</span><span class="o">.</span><span class="n">_getframe</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">sys</span><span class="p">,</span> <span class="s2">"_getframe"</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">stack</span><span class="p">(</span><span class="n">context</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return a list of records for the stack above the caller's frame."""</span>
|
|
<span class="k">return</span> <span class="n">getouterframes</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">_getframe</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">context</span><span class="p">)</span>
|
|
|
|
<div class="viewcode-block" id="trace">
|
|
<a class="viewcode-back" href="../api/evennia.commands.cmdsethandler.html#evennia.commands.cmdsethandler.trace">[docs]</a>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">trace</span><span class="p">(</span><span class="n">context</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return a list of records for the stack below the current exception."""</span>
|
|
<span class="n">exc</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exception</span><span class="p">()</span>
|
|
<span class="n">tb</span> <span class="o">=</span> <span class="kc">None</span> <span class="k">if</span> <span class="n">exc</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">exc</span><span class="o">.</span><span class="n">__traceback__</span>
|
|
<span class="k">return</span> <span class="n">getinnerframes</span><span class="p">(</span><span class="n">tb</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span></div>
|
|
|
|
|
|
|
|
<span class="c1"># ------------------------------------------------ static version of getattr</span>
|
|
|
|
<span class="n">_sentinel</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span>
|
|
<span class="n">_static_getmro</span> <span class="o">=</span> <span class="nb">type</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="s1">'__mro__'</span><span class="p">]</span><span class="o">.</span><span class="fm">__get__</span>
|
|
<span class="n">_get_dunder_dict_of_class</span> <span class="o">=</span> <span class="nb">type</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="s2">"__dict__"</span><span class="p">]</span><span class="o">.</span><span class="fm">__get__</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_check_instance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">attr</span><span class="p">):</span>
|
|
<span class="n">instance_dict</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">instance_dict</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__getattribute__</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s2">"__dict__"</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">return</span> <span class="nb">dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">instance_dict</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="n">_sentinel</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_check_class</span><span class="p">(</span><span class="n">klass</span><span class="p">,</span> <span class="n">attr</span><span class="p">):</span>
|
|
<span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">_static_getmro</span><span class="p">(</span><span class="n">klass</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">_shadowed_dict</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">entry</span><span class="p">))</span> <span class="ow">is</span> <span class="n">_sentinel</span> <span class="ow">and</span> <span class="n">attr</span> <span class="ow">in</span> <span class="n">entry</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">entry</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="n">attr</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="n">_sentinel</span>
|
|
|
|
|
|
<span class="nd">@functools</span><span class="o">.</span><span class="n">lru_cache</span><span class="p">()</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_shadowed_dict_from_weakref_mro_tuple</span><span class="p">(</span><span class="o">*</span><span class="n">weakref_mro</span><span class="p">):</span>
|
|
<span class="k">for</span> <span class="n">weakref_entry</span> <span class="ow">in</span> <span class="n">weakref_mro</span><span class="p">:</span>
|
|
<span class="c1"># Normally we'd have to check whether the result of weakref_entry()</span>
|
|
<span class="c1"># is None here, in case the object the weakref is pointing to has died.</span>
|
|
<span class="c1"># In this specific case, however, we know that the only caller of this</span>
|
|
<span class="c1"># function is `_shadowed_dict()`, and that therefore this weakref is</span>
|
|
<span class="c1"># guaranteed to point to an object that is still alive.</span>
|
|
<span class="n">entry</span> <span class="o">=</span> <span class="n">weakref_entry</span><span class="p">()</span>
|
|
<span class="n">dunder_dict</span> <span class="o">=</span> <span class="n">_get_dunder_dict_of_class</span><span class="p">(</span><span class="n">entry</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="s1">'__dict__'</span> <span class="ow">in</span> <span class="n">dunder_dict</span><span class="p">:</span>
|
|
<span class="n">class_dict</span> <span class="o">=</span> <span class="n">dunder_dict</span><span class="p">[</span><span class="s1">'__dict__'</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">class_dict</span><span class="p">)</span> <span class="ow">is</span> <span class="n">types</span><span class="o">.</span><span class="n">GetSetDescriptorType</span> <span class="ow">and</span>
|
|
<span class="n">class_dict</span><span class="o">.</span><span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__dict__"</span> <span class="ow">and</span>
|
|
<span class="n">class_dict</span><span class="o">.</span><span class="vm">__objclass__</span> <span class="ow">is</span> <span class="n">entry</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">class_dict</span>
|
|
<span class="k">return</span> <span class="n">_sentinel</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_shadowed_dict</span><span class="p">(</span><span class="n">klass</span><span class="p">):</span>
|
|
<span class="c1"># gh-118013: the inner function here is decorated with lru_cache for</span>
|
|
<span class="c1"># performance reasons, *but* make sure not to pass strong references</span>
|
|
<span class="c1"># to the items in the mro. Doing so can lead to unexpected memory</span>
|
|
<span class="c1"># consumption in cases where classes are dynamically created and</span>
|
|
<span class="c1"># destroyed, and the dynamically created classes happen to be the only</span>
|
|
<span class="c1"># objects that hold strong references to other objects that take up a</span>
|
|
<span class="c1"># significant amount of memory.</span>
|
|
<span class="k">return</span> <span class="n">_shadowed_dict_from_weakref_mro_tuple</span><span class="p">(</span>
|
|
<span class="o">*</span><span class="p">[</span><span class="n">make_weakref</span><span class="p">(</span><span class="n">entry</span><span class="p">)</span> <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">_static_getmro</span><span class="p">(</span><span class="n">klass</span><span class="p">)]</span>
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getattr_static</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">_sentinel</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Retrieve attributes without triggering dynamic lookup via the</span>
|
|
<span class="sd"> descriptor protocol, __getattr__ or __getattribute__.</span>
|
|
|
|
<span class="sd"> Note: this function may not be able to retrieve all attributes</span>
|
|
<span class="sd"> that getattr can fetch (like dynamically created attributes)</span>
|
|
<span class="sd"> and may find attributes that getattr can't (like descriptors</span>
|
|
<span class="sd"> that raise AttributeError). It can also return descriptor objects</span>
|
|
<span class="sd"> instead of instance members in some cases. See the</span>
|
|
<span class="sd"> documentation for details.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">instance_result</span> <span class="o">=</span> <span class="n">_sentinel</span>
|
|
|
|
<span class="n">objtype</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">type</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">_static_getmro</span><span class="p">(</span><span class="n">objtype</span><span class="p">):</span>
|
|
<span class="n">klass</span> <span class="o">=</span> <span class="n">objtype</span>
|
|
<span class="n">dict_attr</span> <span class="o">=</span> <span class="n">_shadowed_dict</span><span class="p">(</span><span class="n">klass</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="n">dict_attr</span> <span class="ow">is</span> <span class="n">_sentinel</span> <span class="ow">or</span>
|
|
<span class="nb">type</span><span class="p">(</span><span class="n">dict_attr</span><span class="p">)</span> <span class="ow">is</span> <span class="n">types</span><span class="o">.</span><span class="n">MemberDescriptorType</span><span class="p">):</span>
|
|
<span class="n">instance_result</span> <span class="o">=</span> <span class="n">_check_instance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">attr</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">klass</span> <span class="o">=</span> <span class="n">obj</span>
|
|
|
|
<span class="n">klass_result</span> <span class="o">=</span> <span class="n">_check_class</span><span class="p">(</span><span class="n">klass</span><span class="p">,</span> <span class="n">attr</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">instance_result</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_sentinel</span> <span class="ow">and</span> <span class="n">klass_result</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_sentinel</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">_check_class</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">klass_result</span><span class="p">),</span> <span class="s2">"__get__"</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_sentinel</span> <span class="ow">and</span> <span class="p">(</span>
|
|
<span class="n">_check_class</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">klass_result</span><span class="p">),</span> <span class="s2">"__set__"</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_sentinel</span>
|
|
<span class="ow">or</span> <span class="n">_check_class</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">klass_result</span><span class="p">),</span> <span class="s2">"__delete__"</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_sentinel</span>
|
|
<span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">klass_result</span>
|
|
|
|
<span class="k">if</span> <span class="n">instance_result</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_sentinel</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">instance_result</span>
|
|
<span class="k">if</span> <span class="n">klass_result</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_sentinel</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">klass_result</span>
|
|
|
|
<span class="k">if</span> <span class="n">obj</span> <span class="ow">is</span> <span class="n">klass</span><span class="p">:</span>
|
|
<span class="c1"># for types we check the metaclass too</span>
|
|
<span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">_static_getmro</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">klass</span><span class="p">)):</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="n">_shadowed_dict</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">entry</span><span class="p">))</span> <span class="ow">is</span> <span class="n">_sentinel</span>
|
|
<span class="ow">and</span> <span class="n">attr</span> <span class="ow">in</span> <span class="n">entry</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">entry</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="n">attr</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">default</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_sentinel</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">default</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="n">attr</span><span class="p">)</span>
|
|
|
|
|
|
<span class="c1"># ------------------------------------------------ generator introspection</span>
|
|
|
|
<span class="n">GEN_CREATED</span> <span class="o">=</span> <span class="s1">'GEN_CREATED'</span>
|
|
<span class="n">GEN_RUNNING</span> <span class="o">=</span> <span class="s1">'GEN_RUNNING'</span>
|
|
<span class="n">GEN_SUSPENDED</span> <span class="o">=</span> <span class="s1">'GEN_SUSPENDED'</span>
|
|
<span class="n">GEN_CLOSED</span> <span class="o">=</span> <span class="s1">'GEN_CLOSED'</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getgeneratorstate</span><span class="p">(</span><span class="n">generator</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get current state of a generator-iterator.</span>
|
|
|
|
<span class="sd"> Possible states are:</span>
|
|
<span class="sd"> GEN_CREATED: Waiting to start execution.</span>
|
|
<span class="sd"> GEN_RUNNING: Currently being executed by the interpreter.</span>
|
|
<span class="sd"> GEN_SUSPENDED: Currently suspended at a yield expression.</span>
|
|
<span class="sd"> GEN_CLOSED: Execution has completed.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">generator</span><span class="o">.</span><span class="n">gi_running</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">GEN_RUNNING</span>
|
|
<span class="k">if</span> <span class="n">generator</span><span class="o">.</span><span class="n">gi_suspended</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">GEN_SUSPENDED</span>
|
|
<span class="k">if</span> <span class="n">generator</span><span class="o">.</span><span class="n">gi_frame</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">GEN_CLOSED</span>
|
|
<span class="k">return</span> <span class="n">GEN_CREATED</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getgeneratorlocals</span><span class="p">(</span><span class="n">generator</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Get the mapping of generator local variables to their current values.</span>
|
|
|
|
<span class="sd"> A dict is returned, with the keys the local variable names and values the</span>
|
|
<span class="sd"> bound values."""</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">isgenerator</span><span class="p">(</span><span class="n">generator</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"</span><span class="si">{!r}</span><span class="s2"> is not a Python generator"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">generator</span><span class="p">))</span>
|
|
|
|
<span class="n">frame</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">generator</span><span class="p">,</span> <span class="s2">"gi_frame"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">frame</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">generator</span><span class="o">.</span><span class="n">gi_frame</span><span class="o">.</span><span class="n">f_locals</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="p">{}</span>
|
|
|
|
|
|
<span class="c1"># ------------------------------------------------ coroutine introspection</span>
|
|
|
|
<span class="n">CORO_CREATED</span> <span class="o">=</span> <span class="s1">'CORO_CREATED'</span>
|
|
<span class="n">CORO_RUNNING</span> <span class="o">=</span> <span class="s1">'CORO_RUNNING'</span>
|
|
<span class="n">CORO_SUSPENDED</span> <span class="o">=</span> <span class="s1">'CORO_SUSPENDED'</span>
|
|
<span class="n">CORO_CLOSED</span> <span class="o">=</span> <span class="s1">'CORO_CLOSED'</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getcoroutinestate</span><span class="p">(</span><span class="n">coroutine</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get current state of a coroutine object.</span>
|
|
|
|
<span class="sd"> Possible states are:</span>
|
|
<span class="sd"> CORO_CREATED: Waiting to start execution.</span>
|
|
<span class="sd"> CORO_RUNNING: Currently being executed by the interpreter.</span>
|
|
<span class="sd"> CORO_SUSPENDED: Currently suspended at an await expression.</span>
|
|
<span class="sd"> CORO_CLOSED: Execution has completed.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">coroutine</span><span class="o">.</span><span class="n">cr_running</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">CORO_RUNNING</span>
|
|
<span class="k">if</span> <span class="n">coroutine</span><span class="o">.</span><span class="n">cr_suspended</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">CORO_SUSPENDED</span>
|
|
<span class="k">if</span> <span class="n">coroutine</span><span class="o">.</span><span class="n">cr_frame</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">CORO_CLOSED</span>
|
|
<span class="k">return</span> <span class="n">CORO_CREATED</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getcoroutinelocals</span><span class="p">(</span><span class="n">coroutine</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Get the mapping of coroutine local variables to their current values.</span>
|
|
|
|
<span class="sd"> A dict is returned, with the keys the local variable names and values the</span>
|
|
<span class="sd"> bound values."""</span>
|
|
<span class="n">frame</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">coroutine</span><span class="p">,</span> <span class="s2">"cr_frame"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">frame</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">frame</span><span class="o">.</span><span class="n">f_locals</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="p">{}</span>
|
|
|
|
|
|
<span class="c1"># ----------------------------------- asynchronous generator introspection</span>
|
|
|
|
<span class="n">AGEN_CREATED</span> <span class="o">=</span> <span class="s1">'AGEN_CREATED'</span>
|
|
<span class="n">AGEN_RUNNING</span> <span class="o">=</span> <span class="s1">'AGEN_RUNNING'</span>
|
|
<span class="n">AGEN_SUSPENDED</span> <span class="o">=</span> <span class="s1">'AGEN_SUSPENDED'</span>
|
|
<span class="n">AGEN_CLOSED</span> <span class="o">=</span> <span class="s1">'AGEN_CLOSED'</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getasyncgenstate</span><span class="p">(</span><span class="n">agen</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get current state of an asynchronous generator object.</span>
|
|
|
|
<span class="sd"> Possible states are:</span>
|
|
<span class="sd"> AGEN_CREATED: Waiting to start execution.</span>
|
|
<span class="sd"> AGEN_RUNNING: Currently being executed by the interpreter.</span>
|
|
<span class="sd"> AGEN_SUSPENDED: Currently suspended at a yield expression.</span>
|
|
<span class="sd"> AGEN_CLOSED: Execution has completed.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">agen</span><span class="o">.</span><span class="n">ag_running</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">AGEN_RUNNING</span>
|
|
<span class="k">if</span> <span class="n">agen</span><span class="o">.</span><span class="n">ag_suspended</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">AGEN_SUSPENDED</span>
|
|
<span class="k">if</span> <span class="n">agen</span><span class="o">.</span><span class="n">ag_frame</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">AGEN_CLOSED</span>
|
|
<span class="k">return</span> <span class="n">AGEN_CREATED</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">getasyncgenlocals</span><span class="p">(</span><span class="n">agen</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Get the mapping of asynchronous generator local variables to their current</span>
|
|
<span class="sd"> values.</span>
|
|
|
|
<span class="sd"> A dict is returned, with the keys the local variable names and values the</span>
|
|
<span class="sd"> bound values."""</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">isasyncgen</span><span class="p">(</span><span class="n">agen</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">agen</span><span class="si">!r}</span><span class="s2"> is not a Python async generator"</span><span class="p">)</span>
|
|
|
|
<span class="n">frame</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">agen</span><span class="p">,</span> <span class="s2">"ag_frame"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">frame</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">agen</span><span class="o">.</span><span class="n">ag_frame</span><span class="o">.</span><span class="n">f_locals</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="p">{}</span>
|
|
|
|
|
|
<span class="c1">###############################################################################</span>
|
|
<span class="c1">### Function Signature Object (PEP 362)</span>
|
|
<span class="c1">###############################################################################</span>
|
|
|
|
|
|
<span class="n">_NonUserDefinedCallables</span> <span class="o">=</span> <span class="p">(</span><span class="n">types</span><span class="o">.</span><span class="n">WrapperDescriptorType</span><span class="p">,</span>
|
|
<span class="n">types</span><span class="o">.</span><span class="n">MethodWrapperType</span><span class="p">,</span>
|
|
<span class="n">types</span><span class="o">.</span><span class="n">ClassMethodDescriptorType</span><span class="p">,</span>
|
|
<span class="n">types</span><span class="o">.</span><span class="n">BuiltinFunctionType</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_signature_get_user_defined_method</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">method_name</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">follow_wrapper_chains</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Private helper. Checks if ``cls`` has an attribute</span>
|
|
<span class="sd"> named ``method_name`` and returns it only if it is a</span>
|
|
<span class="sd"> pure python function.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">method_name</span> <span class="o">==</span> <span class="s1">'__new__'</span><span class="p">:</span>
|
|
<span class="n">meth</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">method_name</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">meth</span> <span class="o">=</span> <span class="n">getattr_static</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">method_name</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">meth</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># NOTE: The meth may wraps a non-user-defined callable.</span>
|
|
<span class="c1"># In this case, we treat the meth as non-user-defined callable too.</span>
|
|
<span class="c1"># (e.g. cls.__new__ generated by @warnings.deprecated)</span>
|
|
<span class="n">unwrapped_meth</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="n">follow_wrapper_chains</span><span class="p">:</span>
|
|
<span class="n">unwrapped_meth</span> <span class="o">=</span> <span class="n">unwrap</span><span class="p">(</span><span class="n">meth</span><span class="p">,</span> <span class="n">stop</span><span class="o">=</span><span class="p">(</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="s2">"__signature__"</span><span class="p">)</span>
|
|
<span class="ow">or</span> <span class="n">_signature_is_builtin</span><span class="p">(</span><span class="n">m</span><span class="p">)))</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">meth</span><span class="p">,</span> <span class="n">_NonUserDefinedCallables</span><span class="p">)</span>
|
|
<span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">unwrapped_meth</span><span class="p">,</span> <span class="n">_NonUserDefinedCallables</span><span class="p">)):</span>
|
|
<span class="c1"># Once '__signature__' will be added to 'C'-level</span>
|
|
<span class="c1"># callables, this check won't be necessary</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="n">method_name</span> <span class="o">!=</span> <span class="s1">'__new__'</span><span class="p">:</span>
|
|
<span class="n">meth</span> <span class="o">=</span> <span class="n">_descriptor_get</span><span class="p">(</span><span class="n">meth</span><span class="p">,</span> <span class="bp">cls</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">meth</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_signature_get_partial</span><span class="p">(</span><span class="n">wrapped_sig</span><span class="p">,</span> <span class="n">partial</span><span class="p">,</span> <span class="n">extra_args</span><span class="o">=</span><span class="p">()):</span>
|
|
<span class="w"> </span><span class="sd">"""Private helper to calculate how 'wrapped_sig' signature will</span>
|
|
<span class="sd"> look like after applying a 'functools.partial' object (or alike)</span>
|
|
<span class="sd"> on it.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">old_params</span> <span class="o">=</span> <span class="n">wrapped_sig</span><span class="o">.</span><span class="n">parameters</span>
|
|
<span class="n">new_params</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">(</span><span class="n">old_params</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
|
|
|
|
<span class="n">partial_args</span> <span class="o">=</span> <span class="n">partial</span><span class="o">.</span><span class="n">args</span> <span class="ow">or</span> <span class="p">()</span>
|
|
<span class="n">partial_keywords</span> <span class="o">=</span> <span class="n">partial</span><span class="o">.</span><span class="n">keywords</span> <span class="ow">or</span> <span class="p">{}</span>
|
|
|
|
<span class="k">if</span> <span class="n">extra_args</span><span class="p">:</span>
|
|
<span class="n">partial_args</span> <span class="o">=</span> <span class="n">extra_args</span> <span class="o">+</span> <span class="n">partial_args</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">ba</span> <span class="o">=</span> <span class="n">wrapped_sig</span><span class="o">.</span><span class="n">bind_partial</span><span class="p">(</span><span class="o">*</span><span class="n">partial_args</span><span class="p">,</span> <span class="o">**</span><span class="n">partial_keywords</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s1">'partial object </span><span class="si">{!r}</span><span class="s1"> has incorrect arguments'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">partial</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">ex</span>
|
|
|
|
|
|
<span class="n">transform_to_kwonly</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="k">for</span> <span class="n">param_name</span><span class="p">,</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">old_params</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">arg_value</span> <span class="o">=</span> <span class="n">ba</span><span class="o">.</span><span class="n">arguments</span><span class="p">[</span><span class="n">param_name</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">is</span> <span class="n">_POSITIONAL_ONLY</span><span class="p">:</span>
|
|
<span class="c1"># If positional-only parameter is bound by partial,</span>
|
|
<span class="c1"># it effectively disappears from the signature</span>
|
|
<span class="n">new_params</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">param_name</span><span class="p">)</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">is</span> <span class="n">_POSITIONAL_OR_KEYWORD</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">param_name</span> <span class="ow">in</span> <span class="n">partial_keywords</span><span class="p">:</span>
|
|
<span class="c1"># This means that this parameter, and all parameters</span>
|
|
<span class="c1"># after it should be keyword-only (and var-positional</span>
|
|
<span class="c1"># should be removed). Here's why. Consider the following</span>
|
|
<span class="c1"># function:</span>
|
|
<span class="c1"># foo(a, b, *args, c):</span>
|
|
<span class="c1"># pass</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># "partial(foo, a='spam')" will have the following</span>
|
|
<span class="c1"># signature: "(*, a='spam', b, c)". Because attempting</span>
|
|
<span class="c1"># to call that partial with "(10, 20)" arguments will</span>
|
|
<span class="c1"># raise a TypeError, saying that "a" argument received</span>
|
|
<span class="c1"># multiple values.</span>
|
|
<span class="n">transform_to_kwonly</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="c1"># Set the new default value</span>
|
|
<span class="n">new_params</span><span class="p">[</span><span class="n">param_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">arg_value</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># was passed as a positional argument</span>
|
|
<span class="n">new_params</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">param</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">is</span> <span class="n">_KEYWORD_ONLY</span><span class="p">:</span>
|
|
<span class="c1"># Set the new default value</span>
|
|
<span class="n">new_params</span><span class="p">[</span><span class="n">param_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">arg_value</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">transform_to_kwonly</span><span class="p">:</span>
|
|
<span class="k">assert</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_POSITIONAL_ONLY</span>
|
|
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">is</span> <span class="n">_POSITIONAL_OR_KEYWORD</span><span class="p">:</span>
|
|
<span class="n">new_param</span> <span class="o">=</span> <span class="n">new_params</span><span class="p">[</span><span class="n">param_name</span><span class="p">]</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">kind</span><span class="o">=</span><span class="n">_KEYWORD_ONLY</span><span class="p">)</span>
|
|
<span class="n">new_params</span><span class="p">[</span><span class="n">param_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_param</span>
|
|
<span class="n">new_params</span><span class="o">.</span><span class="n">move_to_end</span><span class="p">(</span><span class="n">param_name</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="n">_KEYWORD_ONLY</span><span class="p">,</span> <span class="n">_VAR_KEYWORD</span><span class="p">):</span>
|
|
<span class="n">new_params</span><span class="o">.</span><span class="n">move_to_end</span><span class="p">(</span><span class="n">param_name</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">is</span> <span class="n">_VAR_POSITIONAL</span><span class="p">:</span>
|
|
<span class="n">new_params</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">param</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">wrapped_sig</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">parameters</span><span class="o">=</span><span class="n">new_params</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_signature_bound_method</span><span class="p">(</span><span class="n">sig</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Private helper to transform signatures for unbound</span>
|
|
<span class="sd"> functions to bound methods.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">params</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">sig</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">params</span> <span class="ow">or</span> <span class="n">params</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="n">_VAR_KEYWORD</span><span class="p">,</span> <span class="n">_KEYWORD_ONLY</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'invalid method signature'</span><span class="p">)</span>
|
|
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">kind</span>
|
|
<span class="k">if</span> <span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="n">_POSITIONAL_OR_KEYWORD</span><span class="p">,</span> <span class="n">_POSITIONAL_ONLY</span><span class="p">):</span>
|
|
<span class="c1"># Drop first parameter:</span>
|
|
<span class="c1"># '(p1, p2[, ...])' -> '(p2[, ...])'</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">kind</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_VAR_POSITIONAL</span><span class="p">:</span>
|
|
<span class="c1"># Unless we add a new parameter type we never</span>
|
|
<span class="c1"># get here</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'invalid argument type'</span><span class="p">)</span>
|
|
<span class="c1"># It's a var-positional parameter.</span>
|
|
<span class="c1"># Do nothing. '(*args[, ...])' -> '(*args[, ...])'</span>
|
|
|
|
<span class="k">return</span> <span class="n">sig</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">parameters</span><span class="o">=</span><span class="n">params</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_signature_is_builtin</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Private helper to test if `obj` is a callable that might</span>
|
|
<span class="sd"> support Argument Clinic's __text_signature__ protocol.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="n">isbuiltin</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="ow">or</span>
|
|
<span class="n">ismethoddescriptor</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="ow">or</span>
|
|
<span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">_NonUserDefinedCallables</span><span class="p">)</span> <span class="ow">or</span>
|
|
<span class="c1"># Can't test 'isinstance(type)' here, as it would</span>
|
|
<span class="c1"># also be True for regular python classes.</span>
|
|
<span class="c1"># Can't use the `in` operator here, as it would</span>
|
|
<span class="c1"># invoke the custom __eq__ method.</span>
|
|
<span class="n">obj</span> <span class="ow">is</span> <span class="nb">type</span> <span class="ow">or</span> <span class="n">obj</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_signature_is_functionlike</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Private helper to test if `obj` is a duck type of FunctionType.</span>
|
|
<span class="sd"> A good example of such objects are functions compiled with</span>
|
|
<span class="sd"> Cython, which have all attributes that a pure Python function</span>
|
|
<span class="sd"> would have, but have their code statically compiled.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">callable</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="ow">or</span> <span class="n">isclass</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="c1"># All function-like objects are obviously callables,</span>
|
|
<span class="c1"># and not classes.</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
|
|
<span class="n">name</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__name__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">code</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__code__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">defaults</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__defaults__'</span><span class="p">,</span> <span class="n">_void</span><span class="p">)</span> <span class="c1"># Important to use _void ...</span>
|
|
<span class="n">kwdefaults</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__kwdefaults__'</span><span class="p">,</span> <span class="n">_void</span><span class="p">)</span> <span class="c1"># ... and not None here</span>
|
|
<span class="n">annotations</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__annotations__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">CodeType</span><span class="p">)</span> <span class="ow">and</span>
|
|
<span class="nb">isinstance</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">and</span>
|
|
<span class="p">(</span><span class="n">defaults</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">defaults</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">))</span> <span class="ow">and</span>
|
|
<span class="p">(</span><span class="n">kwdefaults</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">kwdefaults</span><span class="p">,</span> <span class="nb">dict</span><span class="p">))</span> <span class="ow">and</span>
|
|
<span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">annotations</span><span class="p">,</span> <span class="p">(</span><span class="nb">dict</span><span class="p">))</span> <span class="ow">or</span> <span class="n">annotations</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">)</span> <span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_signature_strip_non_python_syntax</span><span class="p">(</span><span class="n">signature</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Private helper function. Takes a signature in Argument Clinic's</span>
|
|
<span class="sd"> extended signature format.</span>
|
|
|
|
<span class="sd"> Returns a tuple of two things:</span>
|
|
<span class="sd"> * that signature re-rendered in standard Python syntax, and</span>
|
|
<span class="sd"> * the index of the "self" parameter (generally 0), or None if</span>
|
|
<span class="sd"> the function does not have a "self" parameter.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">signature</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">signature</span><span class="p">,</span> <span class="kc">None</span>
|
|
|
|
<span class="n">self_parameter</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="n">lines</span> <span class="o">=</span> <span class="p">[</span><span class="n">l</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">)</span> <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">signature</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span> <span class="k">if</span> <span class="n">l</span><span class="p">]</span>
|
|
<span class="n">generator</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span><span class="o">.</span><span class="fm">__next__</span>
|
|
<span class="n">token_stream</span> <span class="o">=</span> <span class="n">tokenize</span><span class="o">.</span><span class="n">tokenize</span><span class="p">(</span><span class="n">generator</span><span class="p">)</span>
|
|
|
|
<span class="n">text</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">add</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">append</span>
|
|
|
|
<span class="n">current_parameter</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="n">OP</span> <span class="o">=</span> <span class="n">token</span><span class="o">.</span><span class="n">OP</span>
|
|
<span class="n">ERRORTOKEN</span> <span class="o">=</span> <span class="n">token</span><span class="o">.</span><span class="n">ERRORTOKEN</span>
|
|
|
|
<span class="c1"># token stream always starts with ENCODING token, skip it</span>
|
|
<span class="n">t</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">token_stream</span><span class="p">)</span>
|
|
<span class="k">assert</span> <span class="n">t</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">tokenize</span><span class="o">.</span><span class="n">ENCODING</span>
|
|
|
|
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">token_stream</span><span class="p">:</span>
|
|
<span class="nb">type</span><span class="p">,</span> <span class="n">string</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">type</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">string</span>
|
|
|
|
<span class="k">if</span> <span class="nb">type</span> <span class="o">==</span> <span class="n">OP</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">string</span> <span class="o">==</span> <span class="s1">','</span><span class="p">:</span>
|
|
<span class="n">current_parameter</span> <span class="o">+=</span> <span class="mi">1</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="nb">type</span> <span class="o">==</span> <span class="n">OP</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="n">string</span> <span class="o">==</span> <span class="s1">'$'</span><span class="p">):</span>
|
|
<span class="k">assert</span> <span class="n">self_parameter</span> <span class="ow">is</span> <span class="kc">None</span>
|
|
<span class="n">self_parameter</span> <span class="o">=</span> <span class="n">current_parameter</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="n">add</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="n">string</span> <span class="o">==</span> <span class="s1">','</span><span class="p">):</span>
|
|
<span class="n">add</span><span class="p">(</span><span class="s1">' '</span><span class="p">)</span>
|
|
<span class="n">clean_signature</span> <span class="o">=</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">text</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span> <span class="s2">""</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">clean_signature</span><span class="p">,</span> <span class="n">self_parameter</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_signature_fromstr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">skip_bound_arg</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Private helper to parse content of '__text_signature__'</span>
|
|
<span class="sd"> and return a Signature based on it.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">Parameter</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_parameter_cls</span>
|
|
|
|
<span class="n">clean_signature</span><span class="p">,</span> <span class="n">self_parameter</span> <span class="o">=</span> <span class="n">_signature_strip_non_python_syntax</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
|
|
|
|
<span class="n">program</span> <span class="o">=</span> <span class="s2">"def foo"</span> <span class="o">+</span> <span class="n">clean_signature</span> <span class="o">+</span> <span class="s2">": pass"</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">module</span> <span class="o">=</span> <span class="n">ast</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">program</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">SyntaxError</span><span class="p">:</span>
|
|
<span class="n">module</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">Module</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"</span><span class="si">{!r}</span><span class="s2"> builtin has invalid signature"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
|
|
|
|
<span class="n">f</span> <span class="o">=</span> <span class="n">module</span><span class="o">.</span><span class="n">body</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">empty</span> <span class="o">=</span> <span class="n">Parameter</span><span class="o">.</span><span class="n">empty</span>
|
|
|
|
<span class="n">module</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">module_dict</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="n">module_name</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">module_name</span><span class="p">:</span>
|
|
<span class="n">objclass</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__objclass__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">module_name</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">objclass</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">module_name</span><span class="p">:</span>
|
|
<span class="n">module</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">module_name</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">module</span><span class="p">:</span>
|
|
<span class="n">module_dict</span> <span class="o">=</span> <span class="n">module</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="n">sys_module_dict</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">parse_name</span><span class="p">(</span><span class="n">node</span><span class="p">):</span>
|
|
<span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">arg</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">node</span><span class="o">.</span><span class="n">annotation</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Annotations are not currently supported"</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">node</span><span class="o">.</span><span class="n">arg</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">wrap_value</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="nb">eval</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">module_dict</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">NameError</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="nb">eval</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">sys_module_dict</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">NameError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span>
|
|
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">,</span> <span class="nb">bool</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="kc">None</span><span class="p">))):</span>
|
|
<span class="k">return</span> <span class="n">ast</span><span class="o">.</span><span class="n">Constant</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">RewriteSymbolics</span><span class="p">(</span><span class="n">ast</span><span class="o">.</span><span class="n">NodeTransformer</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">visit_Attribute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">):</span>
|
|
<span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">n</span> <span class="o">=</span> <span class="n">node</span>
|
|
<span class="k">while</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">Attribute</span><span class="p">):</span>
|
|
<span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">n</span><span class="o">.</span><span class="n">attr</span><span class="p">)</span>
|
|
<span class="n">n</span> <span class="o">=</span> <span class="n">n</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">Name</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span>
|
|
<span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">n</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="s2">"."</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">reversed</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">wrap_value</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">visit_Name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">ctx</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">Load</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="n">wrap_value</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">visit_BinOp</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">):</span>
|
|
<span class="c1"># Support constant folding of a couple simple binary operations</span>
|
|
<span class="c1"># commonly used to define default values in text signatures</span>
|
|
<span class="n">left</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">visit</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">left</span><span class="p">)</span>
|
|
<span class="n">right</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">visit</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">right</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">left</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">Constant</span><span class="p">)</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">right</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">Constant</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">op</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">Add</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">ast</span><span class="o">.</span><span class="n">Constant</span><span class="p">(</span><span class="n">left</span><span class="o">.</span><span class="n">value</span> <span class="o">+</span> <span class="n">right</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">node</span><span class="o">.</span><span class="n">op</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">Sub</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">ast</span><span class="o">.</span><span class="n">Constant</span><span class="p">(</span><span class="n">left</span><span class="o">.</span><span class="n">value</span> <span class="o">-</span> <span class="n">right</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">node</span><span class="o">.</span><span class="n">op</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">BitOr</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">ast</span><span class="o">.</span><span class="n">Constant</span><span class="p">(</span><span class="n">left</span><span class="o">.</span><span class="n">value</span> <span class="o">|</span> <span class="n">right</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">p</span><span class="p">(</span><span class="n">name_node</span><span class="p">,</span> <span class="n">default_node</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">empty</span><span class="p">):</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">parse_name</span><span class="p">(</span><span class="n">name_node</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">default_node</span> <span class="ow">and</span> <span class="n">default_node</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_empty</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">default_node</span> <span class="o">=</span> <span class="n">RewriteSymbolics</span><span class="p">()</span><span class="o">.</span><span class="n">visit</span><span class="p">(</span><span class="n">default_node</span><span class="p">)</span>
|
|
<span class="n">default</span> <span class="o">=</span> <span class="n">ast</span><span class="o">.</span><span class="n">literal_eval</span><span class="p">(</span><span class="n">default_node</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"</span><span class="si">{!r}</span><span class="s2"> builtin has invalid signature"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
|
|
<span class="n">parameters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Parameter</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">kind</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">default</span><span class="p">,</span> <span class="n">annotation</span><span class="o">=</span><span class="n">empty</span><span class="p">))</span>
|
|
|
|
<span class="c1"># non-keyword-only parameters</span>
|
|
<span class="n">total_non_kw_args</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">posonlyargs</span><span class="p">)</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
|
|
<span class="n">required_non_kw_args</span> <span class="o">=</span> <span class="n">total_non_kw_args</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">defaults</span><span class="p">)</span>
|
|
<span class="n">defaults</span> <span class="o">=</span> <span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="n">itertools</span><span class="o">.</span><span class="n">repeat</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">required_non_kw_args</span><span class="p">),</span> <span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">defaults</span><span class="p">)</span>
|
|
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="n">Parameter</span><span class="o">.</span><span class="n">POSITIONAL_ONLY</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">default</span><span class="p">)</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">posonlyargs</span><span class="p">,</span> <span class="n">defaults</span><span class="p">):</span>
|
|
<span class="n">p</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">default</span><span class="p">)</span>
|
|
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="n">Parameter</span><span class="o">.</span><span class="n">POSITIONAL_OR_KEYWORD</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">default</span><span class="p">)</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">args</span><span class="p">,</span> <span class="n">defaults</span><span class="p">):</span>
|
|
<span class="n">p</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">default</span><span class="p">)</span>
|
|
|
|
<span class="c1"># *args</span>
|
|
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">vararg</span><span class="p">:</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="n">Parameter</span><span class="o">.</span><span class="n">VAR_POSITIONAL</span>
|
|
<span class="n">p</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">vararg</span><span class="p">,</span> <span class="n">empty</span><span class="p">)</span>
|
|
|
|
<span class="c1"># keyword-only arguments</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="n">Parameter</span><span class="o">.</span><span class="n">KEYWORD_ONLY</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">default</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">kwonlyargs</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">kw_defaults</span><span class="p">):</span>
|
|
<span class="n">p</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">default</span><span class="p">)</span>
|
|
|
|
<span class="c1"># **kwargs</span>
|
|
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">kwarg</span><span class="p">:</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="n">Parameter</span><span class="o">.</span><span class="n">VAR_KEYWORD</span>
|
|
<span class="n">p</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">kwarg</span><span class="p">,</span> <span class="n">empty</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">self_parameter</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># Possibly strip the bound argument:</span>
|
|
<span class="c1"># - We *always* strip first bound argument if</span>
|
|
<span class="c1"># it is a module.</span>
|
|
<span class="c1"># - We don't strip first bound argument if</span>
|
|
<span class="c1"># skip_bound_arg is False.</span>
|
|
<span class="k">assert</span> <span class="n">parameters</span>
|
|
<span class="n">_self</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__self__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">self_isbound</span> <span class="o">=</span> <span class="n">_self</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
|
|
<span class="n">self_ismodule</span> <span class="o">=</span> <span class="n">ismodule</span><span class="p">(</span><span class="n">_self</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">self_isbound</span> <span class="ow">and</span> <span class="p">(</span><span class="n">self_ismodule</span> <span class="ow">or</span> <span class="n">skip_bound_arg</span><span class="p">):</span>
|
|
<span class="n">parameters</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># for builtins, self parameter is always positional-only!</span>
|
|
<span class="n">p</span> <span class="o">=</span> <span class="n">parameters</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">kind</span><span class="o">=</span><span class="n">Parameter</span><span class="o">.</span><span class="n">POSITIONAL_ONLY</span><span class="p">)</span>
|
|
<span class="n">parameters</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">p</span>
|
|
|
|
<span class="k">return</span> <span class="bp">cls</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span> <span class="n">return_annotation</span><span class="o">=</span><span class="bp">cls</span><span class="o">.</span><span class="n">empty</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_signature_from_builtin</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="n">skip_bound_arg</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Private helper function to get signature for</span>
|
|
<span class="sd"> builtin callables.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">_signature_is_builtin</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"</span><span class="si">{!r}</span><span class="s2"> is not a Python builtin "</span>
|
|
<span class="s2">"function"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">func</span><span class="p">))</span>
|
|
|
|
<span class="n">s</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s2">"__text_signature__"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"no signature found for builtin </span><span class="si">{!r}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">func</span><span class="p">))</span>
|
|
|
|
<span class="k">return</span> <span class="n">_signature_fromstr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">skip_bound_arg</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_signature_from_function</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="n">skip_bound_arg</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
|
<span class="nb">globals</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="nb">locals</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">eval_str</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Private helper: constructs Signature for the given python function."""</span>
|
|
|
|
<span class="n">is_duck_function</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">isfunction</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">_signature_is_functionlike</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="n">is_duck_function</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># If it's not a pure Python function, and not a duck type</span>
|
|
<span class="c1"># of pure function:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'</span><span class="si">{!r}</span><span class="s1"> is not a Python function'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">func</span><span class="p">))</span>
|
|
|
|
<span class="n">s</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="s2">"__text_signature__"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">s</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">_signature_fromstr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">skip_bound_arg</span><span class="p">)</span>
|
|
|
|
<span class="n">Parameter</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_parameter_cls</span>
|
|
|
|
<span class="c1"># Parameter information.</span>
|
|
<span class="n">func_code</span> <span class="o">=</span> <span class="n">func</span><span class="o">.</span><span class="vm">__code__</span>
|
|
<span class="n">pos_count</span> <span class="o">=</span> <span class="n">func_code</span><span class="o">.</span><span class="n">co_argcount</span>
|
|
<span class="n">arg_names</span> <span class="o">=</span> <span class="n">func_code</span><span class="o">.</span><span class="n">co_varnames</span>
|
|
<span class="n">posonly_count</span> <span class="o">=</span> <span class="n">func_code</span><span class="o">.</span><span class="n">co_posonlyargcount</span>
|
|
<span class="n">positional</span> <span class="o">=</span> <span class="n">arg_names</span><span class="p">[:</span><span class="n">pos_count</span><span class="p">]</span>
|
|
<span class="n">keyword_only_count</span> <span class="o">=</span> <span class="n">func_code</span><span class="o">.</span><span class="n">co_kwonlyargcount</span>
|
|
<span class="n">keyword_only</span> <span class="o">=</span> <span class="n">arg_names</span><span class="p">[</span><span class="n">pos_count</span><span class="p">:</span><span class="n">pos_count</span> <span class="o">+</span> <span class="n">keyword_only_count</span><span class="p">]</span>
|
|
<span class="n">annotations</span> <span class="o">=</span> <span class="n">get_annotations</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="nb">globals</span><span class="o">=</span><span class="nb">globals</span><span class="p">,</span> <span class="nb">locals</span><span class="o">=</span><span class="nb">locals</span><span class="p">,</span> <span class="n">eval_str</span><span class="o">=</span><span class="n">eval_str</span><span class="p">)</span>
|
|
<span class="n">defaults</span> <span class="o">=</span> <span class="n">func</span><span class="o">.</span><span class="vm">__defaults__</span>
|
|
<span class="n">kwdefaults</span> <span class="o">=</span> <span class="n">func</span><span class="o">.</span><span class="vm">__kwdefaults__</span>
|
|
|
|
<span class="k">if</span> <span class="n">defaults</span><span class="p">:</span>
|
|
<span class="n">pos_default_count</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">defaults</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">pos_default_count</span> <span class="o">=</span> <span class="mi">0</span>
|
|
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="p">[]</span>
|
|
|
|
<span class="n">non_default_count</span> <span class="o">=</span> <span class="n">pos_count</span> <span class="o">-</span> <span class="n">pos_default_count</span>
|
|
<span class="n">posonly_left</span> <span class="o">=</span> <span class="n">posonly_count</span>
|
|
|
|
<span class="c1"># Non-keyword-only parameters w/o defaults.</span>
|
|
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">positional</span><span class="p">[:</span><span class="n">non_default_count</span><span class="p">]:</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="n">_POSITIONAL_ONLY</span> <span class="k">if</span> <span class="n">posonly_left</span> <span class="k">else</span> <span class="n">_POSITIONAL_OR_KEYWORD</span>
|
|
<span class="n">annotation</span> <span class="o">=</span> <span class="n">annotations</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">_empty</span><span class="p">)</span>
|
|
<span class="n">parameters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Parameter</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">annotation</span><span class="o">=</span><span class="n">annotation</span><span class="p">,</span>
|
|
<span class="n">kind</span><span class="o">=</span><span class="n">kind</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">posonly_left</span><span class="p">:</span>
|
|
<span class="n">posonly_left</span> <span class="o">-=</span> <span class="mi">1</span>
|
|
|
|
<span class="c1"># ... w/ defaults.</span>
|
|
<span class="k">for</span> <span class="n">offset</span><span class="p">,</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">positional</span><span class="p">[</span><span class="n">non_default_count</span><span class="p">:]):</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="n">_POSITIONAL_ONLY</span> <span class="k">if</span> <span class="n">posonly_left</span> <span class="k">else</span> <span class="n">_POSITIONAL_OR_KEYWORD</span>
|
|
<span class="n">annotation</span> <span class="o">=</span> <span class="n">annotations</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">_empty</span><span class="p">)</span>
|
|
<span class="n">parameters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Parameter</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">annotation</span><span class="o">=</span><span class="n">annotation</span><span class="p">,</span>
|
|
<span class="n">kind</span><span class="o">=</span><span class="n">kind</span><span class="p">,</span>
|
|
<span class="n">default</span><span class="o">=</span><span class="n">defaults</span><span class="p">[</span><span class="n">offset</span><span class="p">]))</span>
|
|
<span class="k">if</span> <span class="n">posonly_left</span><span class="p">:</span>
|
|
<span class="n">posonly_left</span> <span class="o">-=</span> <span class="mi">1</span>
|
|
|
|
<span class="c1"># *args</span>
|
|
<span class="k">if</span> <span class="n">func_code</span><span class="o">.</span><span class="n">co_flags</span> <span class="o">&</span> <span class="n">CO_VARARGS</span><span class="p">:</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">arg_names</span><span class="p">[</span><span class="n">pos_count</span> <span class="o">+</span> <span class="n">keyword_only_count</span><span class="p">]</span>
|
|
<span class="n">annotation</span> <span class="o">=</span> <span class="n">annotations</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">_empty</span><span class="p">)</span>
|
|
<span class="n">parameters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Parameter</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">annotation</span><span class="o">=</span><span class="n">annotation</span><span class="p">,</span>
|
|
<span class="n">kind</span><span class="o">=</span><span class="n">_VAR_POSITIONAL</span><span class="p">))</span>
|
|
|
|
<span class="c1"># Keyword-only parameters.</span>
|
|
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">keyword_only</span><span class="p">:</span>
|
|
<span class="n">default</span> <span class="o">=</span> <span class="n">_empty</span>
|
|
<span class="k">if</span> <span class="n">kwdefaults</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">default</span> <span class="o">=</span> <span class="n">kwdefaults</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">_empty</span><span class="p">)</span>
|
|
|
|
<span class="n">annotation</span> <span class="o">=</span> <span class="n">annotations</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">_empty</span><span class="p">)</span>
|
|
<span class="n">parameters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Parameter</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">annotation</span><span class="o">=</span><span class="n">annotation</span><span class="p">,</span>
|
|
<span class="n">kind</span><span class="o">=</span><span class="n">_KEYWORD_ONLY</span><span class="p">,</span>
|
|
<span class="n">default</span><span class="o">=</span><span class="n">default</span><span class="p">))</span>
|
|
<span class="c1"># **kwargs</span>
|
|
<span class="k">if</span> <span class="n">func_code</span><span class="o">.</span><span class="n">co_flags</span> <span class="o">&</span> <span class="n">CO_VARKEYWORDS</span><span class="p">:</span>
|
|
<span class="n">index</span> <span class="o">=</span> <span class="n">pos_count</span> <span class="o">+</span> <span class="n">keyword_only_count</span>
|
|
<span class="k">if</span> <span class="n">func_code</span><span class="o">.</span><span class="n">co_flags</span> <span class="o">&</span> <span class="n">CO_VARARGS</span><span class="p">:</span>
|
|
<span class="n">index</span> <span class="o">+=</span> <span class="mi">1</span>
|
|
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">arg_names</span><span class="p">[</span><span class="n">index</span><span class="p">]</span>
|
|
<span class="n">annotation</span> <span class="o">=</span> <span class="n">annotations</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">_empty</span><span class="p">)</span>
|
|
<span class="n">parameters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Parameter</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">annotation</span><span class="o">=</span><span class="n">annotation</span><span class="p">,</span>
|
|
<span class="n">kind</span><span class="o">=</span><span class="n">_VAR_KEYWORD</span><span class="p">))</span>
|
|
|
|
<span class="c1"># Is 'func' is a pure Python function - don't validate the</span>
|
|
<span class="c1"># parameters list (for correct order and defaults), it should be OK.</span>
|
|
<span class="k">return</span> <span class="bp">cls</span><span class="p">(</span><span class="n">parameters</span><span class="p">,</span>
|
|
<span class="n">return_annotation</span><span class="o">=</span><span class="n">annotations</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'return'</span><span class="p">,</span> <span class="n">_empty</span><span class="p">),</span>
|
|
<span class="n">__validate_parameters__</span><span class="o">=</span><span class="n">is_duck_function</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_descriptor_get</span><span class="p">(</span><span class="n">descriptor</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">isclass</span><span class="p">(</span><span class="n">descriptor</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">descriptor</span>
|
|
<span class="n">get</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">descriptor</span><span class="p">),</span> <span class="s1">'__get__'</span><span class="p">,</span> <span class="n">_sentinel</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">get</span> <span class="ow">is</span> <span class="n">_sentinel</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">descriptor</span>
|
|
<span class="k">return</span> <span class="n">get</span><span class="p">(</span><span class="n">descriptor</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_signature_from_callable</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span>
|
|
<span class="n">follow_wrapper_chains</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
|
<span class="n">skip_bound_arg</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
|
<span class="nb">globals</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="nb">locals</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">eval_str</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
|
<span class="n">sigcls</span><span class="p">):</span>
|
|
|
|
<span class="w"> </span><span class="sd">"""Private helper function to get signature for arbitrary</span>
|
|
<span class="sd"> callable objects.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">_get_signature_of</span> <span class="o">=</span> <span class="n">functools</span><span class="o">.</span><span class="n">partial</span><span class="p">(</span><span class="n">_signature_from_callable</span><span class="p">,</span>
|
|
<span class="n">follow_wrapper_chains</span><span class="o">=</span><span class="n">follow_wrapper_chains</span><span class="p">,</span>
|
|
<span class="n">skip_bound_arg</span><span class="o">=</span><span class="n">skip_bound_arg</span><span class="p">,</span>
|
|
<span class="nb">globals</span><span class="o">=</span><span class="nb">globals</span><span class="p">,</span>
|
|
<span class="nb">locals</span><span class="o">=</span><span class="nb">locals</span><span class="p">,</span>
|
|
<span class="n">sigcls</span><span class="o">=</span><span class="n">sigcls</span><span class="p">,</span>
|
|
<span class="n">eval_str</span><span class="o">=</span><span class="n">eval_str</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">callable</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'</span><span class="si">{!r}</span><span class="s1"> is not a callable object'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">MethodType</span><span class="p">):</span>
|
|
<span class="c1"># In this case we skip the first parameter of the underlying</span>
|
|
<span class="c1"># function (usually `self` or `cls`).</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="n">_get_signature_of</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="vm">__func__</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">skip_bound_arg</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">_signature_bound_method</span><span class="p">(</span><span class="n">sig</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">sig</span>
|
|
|
|
<span class="c1"># Was this function wrapped by a decorator?</span>
|
|
<span class="k">if</span> <span class="n">follow_wrapper_chains</span><span class="p">:</span>
|
|
<span class="c1"># Unwrap until we find an explicit signature or a MethodType (which will be</span>
|
|
<span class="c1"># handled explicitly below).</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="n">unwrap</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">stop</span><span class="o">=</span><span class="p">(</span><span class="k">lambda</span> <span class="n">f</span><span class="p">:</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s2">"__signature__"</span><span class="p">)</span>
|
|
<span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">f</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="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">types</span><span class="o">.</span><span class="n">MethodType</span><span class="p">):</span>
|
|
<span class="c1"># If the unwrapped object is a *method*, we might want to</span>
|
|
<span class="c1"># skip its first parameter (self).</span>
|
|
<span class="c1"># See test_signature_wrapped_bound_method for details.</span>
|
|
<span class="k">return</span> <span class="n">_get_signature_of</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">__signature__</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">sig</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># since __text_signature__ is not writable on classes, __signature__</span>
|
|
<span class="c1"># may contain text (or be a callable that returns text);</span>
|
|
<span class="c1"># if so, convert it</span>
|
|
<span class="n">o_sig</span> <span class="o">=</span> <span class="n">sig</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sig</span><span class="p">,</span> <span class="p">(</span><span class="n">Signature</span><span class="p">,</span> <span class="nb">str</span><span class="p">))</span> <span class="ow">and</span> <span class="nb">callable</span><span class="p">(</span><span class="n">sig</span><span class="p">):</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="n">sig</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sig</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="n">_signature_fromstr</span><span class="p">(</span><span class="n">sigcls</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">sig</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sig</span><span class="p">,</span> <span class="n">Signature</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s1">'unexpected object </span><span class="si">{!r}</span><span class="s1"> in __signature__ '</span>
|
|
<span class="s1">'attribute'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">o_sig</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">sig</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">partialmethod</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">__partialmethod__</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">partialmethod</span><span class="p">,</span> <span class="n">functools</span><span class="o">.</span><span class="n">partialmethod</span><span class="p">):</span>
|
|
<span class="c1"># Unbound partialmethod (see functools.partialmethod)</span>
|
|
<span class="c1"># This means, that we need to calculate the signature</span>
|
|
<span class="c1"># as if it's a regular partial object, but taking into</span>
|
|
<span class="c1"># account that the first positional argument</span>
|
|
<span class="c1"># (usually `self`, or `cls`) will not be passed</span>
|
|
<span class="c1"># automatically (as for boundmethods)</span>
|
|
|
|
<span class="n">wrapped_sig</span> <span class="o">=</span> <span class="n">_get_signature_of</span><span class="p">(</span><span class="n">partialmethod</span><span class="o">.</span><span class="n">func</span><span class="p">)</span>
|
|
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="n">_signature_get_partial</span><span class="p">(</span><span class="n">wrapped_sig</span><span class="p">,</span> <span class="n">partialmethod</span><span class="p">,</span> <span class="p">(</span><span class="kc">None</span><span class="p">,))</span>
|
|
<span class="n">first_wrapped_param</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">wrapped_sig</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">values</span><span class="p">())[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">first_wrapped_param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">is</span> <span class="n">Parameter</span><span class="o">.</span><span class="n">VAR_POSITIONAL</span><span class="p">:</span>
|
|
<span class="c1"># First argument of the wrapped callable is `*args`, as in</span>
|
|
<span class="c1"># `partialmethod(lambda *args)`.</span>
|
|
<span class="k">return</span> <span class="n">sig</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">sig_params</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">sig</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
|
|
<span class="k">assert</span> <span class="p">(</span><span class="ow">not</span> <span class="n">sig_params</span> <span class="ow">or</span>
|
|
<span class="n">first_wrapped_param</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">sig_params</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
|
<span class="n">new_params</span> <span class="o">=</span> <span class="p">(</span><span class="n">first_wrapped_param</span><span class="p">,)</span> <span class="o">+</span> <span class="n">sig_params</span>
|
|
<span class="k">return</span> <span class="n">sig</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">parameters</span><span class="o">=</span><span class="n">new_params</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">functools</span><span class="o">.</span><span class="n">partial</span><span class="p">):</span>
|
|
<span class="n">wrapped_sig</span> <span class="o">=</span> <span class="n">_get_signature_of</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">func</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_signature_get_partial</span><span class="p">(</span><span class="n">wrapped_sig</span><span class="p">,</span> <span class="n">obj</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">isfunction</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_signature_is_functionlike</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="c1"># If it's a pure Python function, or an object that is duck type</span>
|
|
<span class="c1"># of a Python function (Cython functions, for instance), then:</span>
|
|
<span class="k">return</span> <span class="n">_signature_from_function</span><span class="p">(</span><span class="n">sigcls</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span>
|
|
<span class="n">skip_bound_arg</span><span class="o">=</span><span class="n">skip_bound_arg</span><span class="p">,</span>
|
|
<span class="nb">globals</span><span class="o">=</span><span class="nb">globals</span><span class="p">,</span> <span class="nb">locals</span><span class="o">=</span><span class="nb">locals</span><span class="p">,</span> <span class="n">eval_str</span><span class="o">=</span><span class="n">eval_str</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">_signature_is_builtin</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">_signature_from_builtin</span><span class="p">(</span><span class="n">sigcls</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span>
|
|
<span class="n">skip_bound_arg</span><span class="o">=</span><span class="n">skip_bound_arg</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="c1"># obj is a class or a metaclass</span>
|
|
|
|
<span class="c1"># First, let's see if it has an overloaded __call__ defined</span>
|
|
<span class="c1"># in its metaclass</span>
|
|
<span class="n">call</span> <span class="o">=</span> <span class="n">_signature_get_user_defined_method</span><span class="p">(</span>
|
|
<span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">),</span>
|
|
<span class="s1">'__call__'</span><span class="p">,</span>
|
|
<span class="n">follow_wrapper_chains</span><span class="o">=</span><span class="n">follow_wrapper_chains</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">call</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">_get_signature_of</span><span class="p">(</span><span class="n">call</span><span class="p">)</span>
|
|
|
|
<span class="c1"># NOTE: The user-defined method can be a function with a thin wrapper</span>
|
|
<span class="c1"># around object.__new__ (e.g., generated by `@warnings.deprecated`)</span>
|
|
<span class="n">new</span> <span class="o">=</span> <span class="n">_signature_get_user_defined_method</span><span class="p">(</span>
|
|
<span class="n">obj</span><span class="p">,</span>
|
|
<span class="s1">'__new__'</span><span class="p">,</span>
|
|
<span class="n">follow_wrapper_chains</span><span class="o">=</span><span class="n">follow_wrapper_chains</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="n">init</span> <span class="o">=</span> <span class="n">_signature_get_user_defined_method</span><span class="p">(</span>
|
|
<span class="n">obj</span><span class="p">,</span>
|
|
<span class="s1">'__init__'</span><span class="p">,</span>
|
|
<span class="n">follow_wrapper_chains</span><span class="o">=</span><span class="n">follow_wrapper_chains</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># Go through the MRO and see if any class has user-defined</span>
|
|
<span class="c1"># pure Python __new__ or __init__ method</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">:</span>
|
|
<span class="c1"># Now we check if the 'obj' class has an own '__new__' method</span>
|
|
<span class="k">if</span> <span class="n">new</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="s1">'__new__'</span> <span class="ow">in</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="n">_get_signature_of</span><span class="p">(</span><span class="n">new</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">skip_bound_arg</span><span class="p">:</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="n">_signature_bound_method</span><span class="p">(</span><span class="n">sig</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">sig</span>
|
|
<span class="c1"># or an own '__init__' method</span>
|
|
<span class="k">elif</span> <span class="n">init</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="s1">'__init__'</span> <span class="ow">in</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">_get_signature_of</span><span class="p">(</span><span class="n">init</span><span class="p">)</span>
|
|
|
|
<span class="c1"># At this point we know, that `obj` is a class, with no user-</span>
|
|
<span class="c1"># defined '__init__', '__new__', or class-level '__call__'</span>
|
|
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
|
|
<span class="c1"># Since '__text_signature__' is implemented as a</span>
|
|
<span class="c1"># descriptor that extracts text signature from the</span>
|
|
<span class="c1"># class docstring, if 'obj' is derived from a builtin</span>
|
|
<span class="c1"># class, its own '__text_signature__' may be 'None'.</span>
|
|
<span class="c1"># Therefore, we go through the MRO (except the last</span>
|
|
<span class="c1"># class in there, which is 'object') to find the first</span>
|
|
<span class="c1"># class with non-empty text signature.</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">text_sig</span> <span class="o">=</span> <span class="n">base</span><span class="o">.</span><span class="n">__text_signature__</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">text_sig</span><span class="p">:</span>
|
|
<span class="c1"># If 'base' class has a __text_signature__ attribute:</span>
|
|
<span class="c1"># return a signature based on it</span>
|
|
<span class="k">return</span> <span class="n">_signature_fromstr</span><span class="p">(</span><span class="n">sigcls</span><span class="p">,</span> <span class="n">base</span><span class="p">,</span> <span class="n">text_sig</span><span class="p">)</span>
|
|
|
|
<span class="c1"># No '__text_signature__' was found for the 'obj' class.</span>
|
|
<span class="c1"># Last option is to check if its '__init__' is</span>
|
|
<span class="c1"># object.__init__ or type.__init__.</span>
|
|
<span class="k">if</span> <span class="nb">type</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">:</span>
|
|
<span class="n">obj_init</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="fm">__init__</span>
|
|
<span class="n">obj_new</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="fm">__new__</span>
|
|
<span class="k">if</span> <span class="n">follow_wrapper_chains</span><span class="p">:</span>
|
|
<span class="n">obj_init</span> <span class="o">=</span> <span class="n">unwrap</span><span class="p">(</span><span class="n">obj_init</span><span class="p">)</span>
|
|
<span class="n">obj_new</span> <span class="o">=</span> <span class="n">unwrap</span><span class="p">(</span><span class="n">obj_new</span><span class="p">)</span>
|
|
<span class="c1"># We have a class (not metaclass), but no user-defined</span>
|
|
<span class="c1"># __init__ or __new__ for it</span>
|
|
<span class="k">if</span> <span class="n">obj_init</span> <span class="ow">is</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__init__</span> <span class="ow">and</span> <span class="n">obj_new</span> <span class="ow">is</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__new__</span><span class="p">:</span>
|
|
<span class="c1"># Return a signature of 'object' builtin.</span>
|
|
<span class="k">return</span> <span class="n">sigcls</span><span class="o">.</span><span class="n">from_callable</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
|
<span class="s1">'no signature found for builtin type </span><span class="si">{!r}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
|
|
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># An object with __call__</span>
|
|
<span class="n">call</span> <span class="o">=</span> <span class="n">getattr_static</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">),</span> <span class="s1">'__call__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">call</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">text_sig</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">__text_signature__</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">text_sig</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">_signature_fromstr</span><span class="p">(</span><span class="n">sigcls</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">text_sig</span><span class="p">)</span>
|
|
<span class="n">call</span> <span class="o">=</span> <span class="n">_descriptor_get</span><span class="p">(</span><span class="n">call</span><span class="p">,</span> <span class="n">obj</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">_get_signature_of</span><span class="p">(</span><span class="n">call</span><span class="p">)</span>
|
|
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'callable </span><span class="si">{!r}</span><span class="s1"> is not supported by signature'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_void</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""A private marker - used in Parameter & Signature."""</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_empty</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Marker object for Signature.empty and Parameter.empty."""</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_ParameterKind</span><span class="p">(</span><span class="n">enum</span><span class="o">.</span><span class="n">IntEnum</span><span class="p">):</span>
|
|
<span class="n">POSITIONAL_ONLY</span> <span class="o">=</span> <span class="s1">'positional-only'</span>
|
|
<span class="n">POSITIONAL_OR_KEYWORD</span> <span class="o">=</span> <span class="s1">'positional or keyword'</span>
|
|
<span class="n">VAR_POSITIONAL</span> <span class="o">=</span> <span class="s1">'variadic positional'</span>
|
|
<span class="n">KEYWORD_ONLY</span> <span class="o">=</span> <span class="s1">'keyword-only'</span>
|
|
<span class="n">VAR_KEYWORD</span> <span class="o">=</span> <span class="s1">'variadic keyword'</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">description</span><span class="p">):</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">__members__</span><span class="p">)</span>
|
|
<span class="n">member</span> <span class="o">=</span> <span class="nb">int</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
|
|
<span class="n">member</span><span class="o">.</span><span class="n">_value_</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="n">member</span><span class="o">.</span><span class="n">description</span> <span class="o">=</span> <span class="n">description</span>
|
|
<span class="k">return</span> <span class="n">member</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
|
|
|
|
<span class="n">_POSITIONAL_ONLY</span> <span class="o">=</span> <span class="n">_ParameterKind</span><span class="o">.</span><span class="n">POSITIONAL_ONLY</span>
|
|
<span class="n">_POSITIONAL_OR_KEYWORD</span> <span class="o">=</span> <span class="n">_ParameterKind</span><span class="o">.</span><span class="n">POSITIONAL_OR_KEYWORD</span>
|
|
<span class="n">_VAR_POSITIONAL</span> <span class="o">=</span> <span class="n">_ParameterKind</span><span class="o">.</span><span class="n">VAR_POSITIONAL</span>
|
|
<span class="n">_KEYWORD_ONLY</span> <span class="o">=</span> <span class="n">_ParameterKind</span><span class="o">.</span><span class="n">KEYWORD_ONLY</span>
|
|
<span class="n">_VAR_KEYWORD</span> <span class="o">=</span> <span class="n">_ParameterKind</span><span class="o">.</span><span class="n">VAR_KEYWORD</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">Parameter</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Represents a parameter in a function signature.</span>
|
|
|
|
<span class="sd"> Has the following public attributes:</span>
|
|
|
|
<span class="sd"> * name : str</span>
|
|
<span class="sd"> The name of the parameter as a string.</span>
|
|
<span class="sd"> * default : object</span>
|
|
<span class="sd"> The default value for the parameter if specified. If the</span>
|
|
<span class="sd"> parameter has no default value, this attribute is set to</span>
|
|
<span class="sd"> `Parameter.empty`.</span>
|
|
<span class="sd"> * annotation</span>
|
|
<span class="sd"> The annotation for the parameter if specified. If the</span>
|
|
<span class="sd"> parameter has no annotation, this attribute is set to</span>
|
|
<span class="sd"> `Parameter.empty`.</span>
|
|
<span class="sd"> * kind : str</span>
|
|
<span class="sd"> Describes how argument values are bound to the parameter.</span>
|
|
<span class="sd"> Possible values: `Parameter.POSITIONAL_ONLY`,</span>
|
|
<span class="sd"> `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,</span>
|
|
<span class="sd"> `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'_name'</span><span class="p">,</span> <span class="s1">'_kind'</span><span class="p">,</span> <span class="s1">'_default'</span><span class="p">,</span> <span class="s1">'_annotation'</span><span class="p">)</span>
|
|
|
|
<span class="n">POSITIONAL_ONLY</span> <span class="o">=</span> <span class="n">_POSITIONAL_ONLY</span>
|
|
<span class="n">POSITIONAL_OR_KEYWORD</span> <span class="o">=</span> <span class="n">_POSITIONAL_OR_KEYWORD</span>
|
|
<span class="n">VAR_POSITIONAL</span> <span class="o">=</span> <span class="n">_VAR_POSITIONAL</span>
|
|
<span class="n">KEYWORD_ONLY</span> <span class="o">=</span> <span class="n">_KEYWORD_ONLY</span>
|
|
<span class="n">VAR_KEYWORD</span> <span class="o">=</span> <span class="n">_VAR_KEYWORD</span>
|
|
|
|
<span class="n">empty</span> <span class="o">=</span> <span class="n">_empty</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">kind</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">_empty</span><span class="p">,</span> <span class="n">annotation</span><span class="o">=</span><span class="n">_empty</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_kind</span> <span class="o">=</span> <span class="n">_ParameterKind</span><span class="p">(</span><span class="n">kind</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'value </span><span class="si">{</span><span class="n">kind</span><span class="si">!r}</span><span class="s1"> is not a valid Parameter.kind'</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">default</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_empty</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_kind</span> <span class="ow">in</span> <span class="p">(</span><span class="n">_VAR_POSITIONAL</span><span class="p">,</span> <span class="n">_VAR_KEYWORD</span><span class="p">):</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s1">'</span><span class="si">{}</span><span class="s1"> parameters cannot have default values'</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_kind</span><span class="o">.</span><span class="n">description</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_default</span> <span class="o">=</span> <span class="n">default</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_annotation</span> <span class="o">=</span> <span class="n">annotation</span>
|
|
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">is</span> <span class="n">_empty</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'name is a required attribute for Parameter'</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s1">'name must be a str, not a </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">name</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'.'</span> <span class="ow">and</span> <span class="n">name</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span>
|
|
<span class="c1"># These are implicit arguments generated by comprehensions. In</span>
|
|
<span class="c1"># order to provide a friendlier interface to users, we recast</span>
|
|
<span class="c1"># their name as "implicitN" and treat them as positional-only.</span>
|
|
<span class="c1"># See issue 19611.</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_kind</span> <span class="o">!=</span> <span class="n">_POSITIONAL_OR_KEYWORD</span><span class="p">:</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="s1">'implicit arguments must be passed as '</span>
|
|
<span class="s1">'positional or keyword arguments, not </span><span class="si">{}</span><span class="s1">'</span>
|
|
<span class="p">)</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_kind</span><span class="o">.</span><span class="n">description</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_kind</span> <span class="o">=</span> <span class="n">_POSITIONAL_ONLY</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="s1">'implicit</span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">name</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
|
|
|
|
<span class="c1"># It's possible for C functions to have a positional-only parameter</span>
|
|
<span class="c1"># where the name is a keyword, so for compatibility we'll allow it.</span>
|
|
<span class="n">is_keyword</span> <span class="o">=</span> <span class="n">iskeyword</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_kind</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_POSITIONAL_ONLY</span>
|
|
<span class="k">if</span> <span class="n">is_keyword</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">name</span><span class="o">.</span><span class="n">isidentifier</span><span class="p">():</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'</span><span class="si">{!r}</span><span class="s1"> is not a valid parameter name'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="n">name</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span>
|
|
<span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_kind</span><span class="p">),</span>
|
|
<span class="p">{</span><span class="s1">'_default'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default</span><span class="p">,</span>
|
|
<span class="s1">'_annotation'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_annotation</span><span class="p">})</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__setstate__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">state</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_default</span> <span class="o">=</span> <span class="n">state</span><span class="p">[</span><span class="s1">'_default'</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_annotation</span> <span class="o">=</span> <span class="n">state</span><span class="p">[</span><span class="s1">'_annotation'</span><span class="p">]</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">default</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">annotation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_annotation</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">kind</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_kind</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">replace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">_void</span><span class="p">,</span> <span class="n">kind</span><span class="o">=</span><span class="n">_void</span><span class="p">,</span>
|
|
<span class="n">annotation</span><span class="o">=</span><span class="n">_void</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">_void</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Creates a customized copy of the Parameter."""</span>
|
|
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">is</span> <span class="n">_void</span><span class="p">:</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>
|
|
|
|
<span class="k">if</span> <span class="n">kind</span> <span class="ow">is</span> <span class="n">_void</span><span class="p">:</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_kind</span>
|
|
|
|
<span class="k">if</span> <span class="n">annotation</span> <span class="ow">is</span> <span class="n">_void</span><span class="p">:</span>
|
|
<span class="n">annotation</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_annotation</span>
|
|
|
|
<span class="k">if</span> <span class="n">default</span> <span class="ow">is</span> <span class="n">_void</span><span class="p">:</span>
|
|
<span class="n">default</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default</span>
|
|
|
|
<span class="k">return</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)(</span><span class="n">name</span><span class="p">,</span> <span class="n">kind</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">default</span><span class="p">,</span> <span class="n">annotation</span><span class="o">=</span><span class="n">annotation</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">kind</span>
|
|
<span class="n">formatted</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>
|
|
|
|
<span class="c1"># Add annotation and default value</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_annotation</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_empty</span><span class="p">:</span>
|
|
<span class="n">formatted</span> <span class="o">=</span> <span class="s1">'</span><span class="si">{}</span><span class="s1">: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">formatted</span><span class="p">,</span>
|
|
<span class="n">formatannotation</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_annotation</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_empty</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_annotation</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_empty</span><span class="p">:</span>
|
|
<span class="n">formatted</span> <span class="o">=</span> <span class="s1">'</span><span class="si">{}</span><span class="s1"> = </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">formatted</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_default</span><span class="p">))</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">formatted</span> <span class="o">=</span> <span class="s1">'</span><span class="si">{}</span><span class="s1">=</span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">formatted</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_default</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="n">kind</span> <span class="o">==</span> <span class="n">_VAR_POSITIONAL</span><span class="p">:</span>
|
|
<span class="n">formatted</span> <span class="o">=</span> <span class="s1">'*'</span> <span class="o">+</span> <span class="n">formatted</span>
|
|
<span class="k">elif</span> <span class="n">kind</span> <span class="o">==</span> <span class="n">_VAR_KEYWORD</span><span class="p">:</span>
|
|
<span class="n">formatted</span> <span class="o">=</span> <span class="s1">'**'</span> <span class="o">+</span> <span class="n">formatted</span>
|
|
|
|
<span class="k">return</span> <span class="n">formatted</span>
|
|
|
|
<span class="n">__replace__</span> <span class="o">=</span> <span class="n">replace</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="s1">'<</span><span class="si">{}</span><span class="s1"> "</span><span class="si">{}</span><span class="s1">">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">hash</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_kind</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_annotation</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span> <span class="ow">is</span> <span class="n">other</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Parameter</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_name</span> <span class="ow">and</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_kind</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_kind</span> <span class="ow">and</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_default</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_default</span> <span class="ow">and</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_annotation</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_annotation</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">BoundArguments</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Result of `Signature.bind` call. Holds the mapping of arguments</span>
|
|
<span class="sd"> to the function's parameters.</span>
|
|
|
|
<span class="sd"> Has the following public attributes:</span>
|
|
|
|
<span class="sd"> * arguments : dict</span>
|
|
<span class="sd"> An ordered mutable mapping of parameters' names to arguments' values.</span>
|
|
<span class="sd"> Does not contain arguments' default values.</span>
|
|
<span class="sd"> * signature : Signature</span>
|
|
<span class="sd"> The Signature object that created this instance.</span>
|
|
<span class="sd"> * args : tuple</span>
|
|
<span class="sd"> Tuple of positional arguments values.</span>
|
|
<span class="sd"> * kwargs : dict</span>
|
|
<span class="sd"> Dict of keyword arguments values.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'arguments'</span><span class="p">,</span> <span class="s1">'_signature'</span><span class="p">,</span> <span class="s1">'__weakref__'</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">signature</span><span class="p">,</span> <span class="n">arguments</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">arguments</span> <span class="o">=</span> <span class="n">arguments</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_signature</span> <span class="o">=</span> <span class="n">signature</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">signature</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_signature</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">args</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">param_name</span><span class="p">,</span> <span class="n">param</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_signature</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="n">_VAR_KEYWORD</span><span class="p">,</span> <span class="n">_KEYWORD_ONLY</span><span class="p">):</span>
|
|
<span class="k">break</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">arg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="p">[</span><span class="n">param_name</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="c1"># We're done here. Other arguments</span>
|
|
<span class="c1"># will be mapped in 'BoundArguments.kwargs'</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="n">_VAR_POSITIONAL</span><span class="p">:</span>
|
|
<span class="c1"># *args</span>
|
|
<span class="n">args</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># plain argument</span>
|
|
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">kwargs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">kwargs</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">kwargs_started</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="k">for</span> <span class="n">param_name</span><span class="p">,</span> <span class="n">param</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_signature</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">kwargs_started</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="n">_VAR_KEYWORD</span><span class="p">,</span> <span class="n">_KEYWORD_ONLY</span><span class="p">):</span>
|
|
<span class="n">kwargs_started</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">param_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="p">:</span>
|
|
<span class="n">kwargs_started</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">kwargs_started</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">arg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="p">[</span><span class="n">param_name</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="n">_VAR_KEYWORD</span><span class="p">:</span>
|
|
<span class="c1"># **kwargs</span>
|
|
<span class="n">kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># plain keyword argument</span>
|
|
<span class="n">kwargs</span><span class="p">[</span><span class="n">param_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">arg</span>
|
|
|
|
<span class="k">return</span> <span class="n">kwargs</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">apply_defaults</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Set default values for missing arguments.</span>
|
|
|
|
<span class="sd"> For variable-positional arguments (*args) the default is an</span>
|
|
<span class="sd"> empty tuple.</span>
|
|
|
|
<span class="sd"> For variable-keyword arguments (**kwargs) the default is an</span>
|
|
<span class="sd"> empty dict.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">arguments</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span>
|
|
<span class="n">new_arguments</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">param</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_signature</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">new_arguments</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">name</span><span class="p">,</span> <span class="n">arguments</span><span class="p">[</span><span class="n">name</span><span class="p">]))</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">default</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_empty</span><span class="p">:</span>
|
|
<span class="n">val</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="n">default</span>
|
|
<span class="k">elif</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">is</span> <span class="n">_VAR_POSITIONAL</span><span class="p">:</span>
|
|
<span class="n">val</span> <span class="o">=</span> <span class="p">()</span>
|
|
<span class="k">elif</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">is</span> <span class="n">_VAR_KEYWORD</span><span class="p">:</span>
|
|
<span class="n">val</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># This BoundArguments was likely produced by</span>
|
|
<span class="c1"># Signature.bind_partial().</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">new_arguments</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">name</span><span class="p">,</span> <span class="n">val</span><span class="p">))</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">arguments</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">new_arguments</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span> <span class="ow">is</span> <span class="n">other</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">BoundArguments</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">signature</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">signature</span> <span class="ow">and</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">arguments</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">arguments</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__setstate__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">state</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_signature</span> <span class="o">=</span> <span class="n">state</span><span class="p">[</span><span class="s1">'_signature'</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">arguments</span> <span class="o">=</span> <span class="n">state</span><span class="p">[</span><span class="s1">'arguments'</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__getstate__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="p">{</span><span class="s1">'_signature'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_signature</span><span class="p">,</span> <span class="s1">'arguments'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="p">}</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">arg</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'</span><span class="si">{}</span><span class="s1">=</span><span class="si">{!r}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">value</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="s1">'<</span><span class="si">{}</span><span class="s1"> (</span><span class="si">{}</span><span class="s1">)>'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">args</span><span class="p">))</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">Signature</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""A Signature object represents the overall signature of a function.</span>
|
|
<span class="sd"> It stores a Parameter object for each parameter accepted by the</span>
|
|
<span class="sd"> function, as well as information specific to the function itself.</span>
|
|
|
|
<span class="sd"> A Signature object has the following public attributes and methods:</span>
|
|
|
|
<span class="sd"> * parameters : OrderedDict</span>
|
|
<span class="sd"> An ordered mapping of parameters' names to the corresponding</span>
|
|
<span class="sd"> Parameter objects (keyword-only arguments are in the same order</span>
|
|
<span class="sd"> as listed in `code.co_varnames`).</span>
|
|
<span class="sd"> * return_annotation : object</span>
|
|
<span class="sd"> The annotation for the return type of the function if specified.</span>
|
|
<span class="sd"> If the function has no annotation for its return type, this</span>
|
|
<span class="sd"> attribute is set to `Signature.empty`.</span>
|
|
<span class="sd"> * bind(*args, **kwargs) -> BoundArguments</span>
|
|
<span class="sd"> Creates a mapping from positional and keyword arguments to</span>
|
|
<span class="sd"> parameters.</span>
|
|
<span class="sd"> * bind_partial(*args, **kwargs) -> BoundArguments</span>
|
|
<span class="sd"> Creates a partial mapping from positional and keyword arguments</span>
|
|
<span class="sd"> to parameters (simulating 'functools.partial' behavior.)</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'_return_annotation'</span><span class="p">,</span> <span class="s1">'_parameters'</span><span class="p">)</span>
|
|
|
|
<span class="n">_parameter_cls</span> <span class="o">=</span> <span class="n">Parameter</span>
|
|
<span class="n">_bound_arguments_cls</span> <span class="o">=</span> <span class="n">BoundArguments</span>
|
|
|
|
<span class="n">empty</span> <span class="o">=</span> <span class="n">_empty</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parameters</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">return_annotation</span><span class="o">=</span><span class="n">_empty</span><span class="p">,</span>
|
|
<span class="n">__validate_parameters__</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Constructs Signature from the given list of Parameter</span>
|
|
<span class="sd"> objects and 'return_annotation'. All arguments are optional.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">if</span> <span class="n">parameters</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">()</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">__validate_parameters__</span><span class="p">:</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">()</span>
|
|
<span class="n">top_kind</span> <span class="o">=</span> <span class="n">_POSITIONAL_ONLY</span>
|
|
<span class="n">seen_default</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">parameters</span><span class="p">:</span>
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="n">name</span>
|
|
|
|
<span class="k">if</span> <span class="n">kind</span> <span class="o"><</span> <span class="n">top_kind</span><span class="p">:</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="s1">'wrong parameter order: </span><span class="si">{}</span><span class="s1"> parameter before </span><span class="si">{}</span><span class="s1"> '</span>
|
|
<span class="s1">'parameter'</span>
|
|
<span class="p">)</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">top_kind</span><span class="o">.</span><span class="n">description</span><span class="p">,</span>
|
|
<span class="n">kind</span><span class="o">.</span><span class="n">description</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">kind</span> <span class="o">></span> <span class="n">top_kind</span><span class="p">:</span>
|
|
<span class="n">top_kind</span> <span class="o">=</span> <span class="n">kind</span>
|
|
|
|
<span class="k">if</span> <span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="n">_POSITIONAL_ONLY</span><span class="p">,</span> <span class="n">_POSITIONAL_OR_KEYWORD</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">default</span> <span class="ow">is</span> <span class="n">_empty</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">seen_default</span><span class="p">:</span>
|
|
<span class="c1"># No default for this parameter, but the</span>
|
|
<span class="c1"># previous parameter of had a default</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s1">'non-default argument follows default '</span> \
|
|
<span class="s1">'argument'</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># There is a default for this parameter.</span>
|
|
<span class="n">seen_default</span> <span class="o">=</span> <span class="kc">True</span>
|
|
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">params</span><span class="p">:</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s1">'duplicate parameter name: </span><span class="si">{!r}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
|
|
|
|
<span class="n">params</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">param</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">((</span><span class="n">param</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">param</span><span class="p">)</span> <span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">parameters</span><span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_parameters</span> <span class="o">=</span> <span class="n">types</span><span class="o">.</span><span class="n">MappingProxyType</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_return_annotation</span> <span class="o">=</span> <span class="n">return_annotation</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">from_callable</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span>
|
|
<span class="n">follow_wrapped</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="nb">globals</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="nb">locals</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">eval_str</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Constructs Signature for the given callable object."""</span>
|
|
<span class="k">return</span> <span class="n">_signature_from_callable</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">sigcls</span><span class="o">=</span><span class="bp">cls</span><span class="p">,</span>
|
|
<span class="n">follow_wrapper_chains</span><span class="o">=</span><span class="n">follow_wrapped</span><span class="p">,</span>
|
|
<span class="nb">globals</span><span class="o">=</span><span class="nb">globals</span><span class="p">,</span> <span class="nb">locals</span><span class="o">=</span><span class="nb">locals</span><span class="p">,</span> <span class="n">eval_str</span><span class="o">=</span><span class="n">eval_str</span><span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">parameters</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parameters</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">return_annotation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_return_annotation</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">replace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">parameters</span><span class="o">=</span><span class="n">_void</span><span class="p">,</span> <span class="n">return_annotation</span><span class="o">=</span><span class="n">_void</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Creates a customized copy of the Signature.</span>
|
|
<span class="sd"> Pass 'parameters' and/or 'return_annotation' arguments</span>
|
|
<span class="sd"> to override them in the new copy.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">if</span> <span class="n">parameters</span> <span class="ow">is</span> <span class="n">_void</span><span class="p">:</span>
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
|
|
|
|
<span class="k">if</span> <span class="n">return_annotation</span> <span class="ow">is</span> <span class="n">_void</span><span class="p">:</span>
|
|
<span class="n">return_annotation</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_return_annotation</span>
|
|
|
|
<span class="k">return</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)(</span><span class="n">parameters</span><span class="p">,</span>
|
|
<span class="n">return_annotation</span><span class="o">=</span><span class="n">return_annotation</span><span class="p">)</span>
|
|
|
|
<span class="n">__replace__</span> <span class="o">=</span> <span class="n">replace</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_hash_basis</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">param</span> <span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">!=</span> <span class="n">_KEYWORD_ONLY</span><span class="p">)</span>
|
|
|
|
<span class="n">kwo_params</span> <span class="o">=</span> <span class="p">{</span><span class="n">param</span><span class="o">.</span><span class="n">name</span><span class="p">:</span> <span class="n">param</span> <span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="n">_KEYWORD_ONLY</span><span class="p">}</span>
|
|
|
|
<span class="k">return</span> <span class="n">params</span><span class="p">,</span> <span class="n">kwo_params</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">return_annotation</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">params</span><span class="p">,</span> <span class="n">kwo_params</span><span class="p">,</span> <span class="n">return_annotation</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_hash_basis</span><span class="p">()</span>
|
|
<span class="n">kwo_params</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">(</span><span class="n">kwo_params</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
|
|
<span class="k">return</span> <span class="nb">hash</span><span class="p">((</span><span class="n">params</span><span class="p">,</span> <span class="n">kwo_params</span><span class="p">,</span> <span class="n">return_annotation</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span> <span class="ow">is</span> <span class="n">other</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Signature</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_hash_basis</span><span class="p">()</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_hash_basis</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_bind</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">partial</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Private method. Don't use directly."""</span>
|
|
|
|
<span class="n">arguments</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="n">parameters</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
|
|
<span class="n">parameters_ex</span> <span class="o">=</span> <span class="p">()</span>
|
|
<span class="n">arg_vals</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
|
|
|
|
<span class="n">pos_only_param_in_kwargs</span> <span class="o">=</span> <span class="p">[]</span>
|
|
|
|
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
|
<span class="c1"># Let's iterate through the positional arguments and corresponding</span>
|
|
<span class="c1"># parameters</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">arg_val</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">arg_vals</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">StopIteration</span><span class="p">:</span>
|
|
<span class="c1"># No more positional arguments</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">param</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">parameters</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">StopIteration</span><span class="p">:</span>
|
|
<span class="c1"># No more parameters. That's it. Just need to check that</span>
|
|
<span class="c1"># we have no `kwargs` after this while loop</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="n">_VAR_POSITIONAL</span><span class="p">:</span>
|
|
<span class="c1"># That's OK, just empty *args. Let's start parsing</span>
|
|
<span class="c1"># kwargs</span>
|
|
<span class="k">break</span>
|
|
<span class="k">elif</span> <span class="n">param</span><span class="o">.</span><span class="n">name</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="n">_POSITIONAL_ONLY</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">default</span> <span class="ow">is</span> <span class="n">_empty</span><span class="p">:</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">'missing a required positional-only argument: </span><span class="si">{</span><span class="n">param</span><span class="o">.</span><span class="n">name</span><span class="si">!r}</span><span class="s1">'</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
|
|
<span class="c1"># Raise a TypeError once we are sure there is no</span>
|
|
<span class="c1"># **kwargs param later.</span>
|
|
<span class="n">pos_only_param_in_kwargs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">param</span><span class="p">)</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">parameters_ex</span> <span class="o">=</span> <span class="p">(</span><span class="n">param</span><span class="p">,)</span>
|
|
<span class="k">break</span>
|
|
<span class="k">elif</span> <span class="p">(</span><span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="n">_VAR_KEYWORD</span> <span class="ow">or</span>
|
|
<span class="n">param</span><span class="o">.</span><span class="n">default</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_empty</span><span class="p">):</span>
|
|
<span class="c1"># That's fine too - we have a default value for this</span>
|
|
<span class="c1"># parameter. So, lets start parsing `kwargs`, starting</span>
|
|
<span class="c1"># with the current parameter</span>
|
|
<span class="n">parameters_ex</span> <span class="o">=</span> <span class="p">(</span><span class="n">param</span><span class="p">,)</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># No default, not VAR_KEYWORD, not VAR_POSITIONAL,</span>
|
|
<span class="c1"># not in `kwargs`</span>
|
|
<span class="k">if</span> <span class="n">partial</span><span class="p">:</span>
|
|
<span class="n">parameters_ex</span> <span class="o">=</span> <span class="p">(</span><span class="n">param</span><span class="p">,)</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="n">_KEYWORD_ONLY</span><span class="p">:</span>
|
|
<span class="n">argtype</span> <span class="o">=</span> <span class="s1">' keyword-only'</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">argtype</span> <span class="o">=</span> <span class="s1">''</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s1">'missing a required</span><span class="si">{argtype}</span><span class="s1"> argument: </span><span class="si">{arg!r}</span><span class="s1">'</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">arg</span><span class="o">=</span><span class="n">param</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">argtype</span><span class="o">=</span><span class="n">argtype</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># We have a positional argument to process</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">param</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">parameters</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">StopIteration</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'too many positional arguments'</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="n">_VAR_KEYWORD</span><span class="p">,</span> <span class="n">_KEYWORD_ONLY</span><span class="p">):</span>
|
|
<span class="c1"># Looks like we have no parameter for this positional</span>
|
|
<span class="c1"># argument</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s1">'too many positional arguments'</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
|
|
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="n">_VAR_POSITIONAL</span><span class="p">:</span>
|
|
<span class="c1"># We have an '*args'-like argument, let's fill it with</span>
|
|
<span class="c1"># all positional arguments we have left and move on to</span>
|
|
<span class="c1"># the next phase</span>
|
|
<span class="n">values</span> <span class="o">=</span> <span class="p">[</span><span class="n">arg_val</span><span class="p">]</span>
|
|
<span class="n">values</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">arg_vals</span><span class="p">)</span>
|
|
<span class="n">arguments</span><span class="p">[</span><span class="n">param</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
|
|
<span class="k">break</span>
|
|
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">name</span> <span class="ow">in</span> <span class="n">kwargs</span> <span class="ow">and</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">!=</span> <span class="n">_POSITIONAL_ONLY</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s1">'multiple values for argument </span><span class="si">{arg!r}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
|
<span class="n">arg</span><span class="o">=</span><span class="n">param</span><span class="o">.</span><span class="n">name</span><span class="p">))</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
|
|
|
|
<span class="n">arguments</span><span class="p">[</span><span class="n">param</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">arg_val</span>
|
|
|
|
<span class="c1"># Now, we iterate through the remaining parameters to process</span>
|
|
<span class="c1"># keyword arguments</span>
|
|
<span class="n">kwargs_param</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="n">parameters_ex</span><span class="p">,</span> <span class="n">parameters</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="n">_VAR_KEYWORD</span><span class="p">:</span>
|
|
<span class="c1"># Memorize that we have a '**kwargs'-like parameter</span>
|
|
<span class="n">kwargs_param</span> <span class="o">=</span> <span class="n">param</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="k">if</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="n">_VAR_POSITIONAL</span><span class="p">:</span>
|
|
<span class="c1"># Named arguments don't refer to '*args'-like parameters.</span>
|
|
<span class="c1"># We only arrive here if the positional arguments ended</span>
|
|
<span class="c1"># before reaching the last parameter before *args.</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="n">param_name</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="n">name</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">arg_val</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">param_name</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="c1"># We have no value for this parameter. It's fine though,</span>
|
|
<span class="c1"># if it has a default value, or it is an '*args'-like</span>
|
|
<span class="c1"># parameter, left alone by the processing of positional</span>
|
|
<span class="c1"># arguments.</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="ow">not</span> <span class="n">partial</span> <span class="ow">and</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span> <span class="o">!=</span> <span class="n">_VAR_POSITIONAL</span> <span class="ow">and</span>
|
|
<span class="n">param</span><span class="o">.</span><span class="n">default</span> <span class="ow">is</span> <span class="n">_empty</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'missing a required argument: </span><span class="si">{arg!r}</span><span class="s1">'</span><span class="o">.</span> \
|
|
<span class="nb">format</span><span class="p">(</span><span class="n">arg</span><span class="o">=</span><span class="n">param_name</span><span class="p">))</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
|
|
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">arguments</span><span class="p">[</span><span class="n">param_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">arg_val</span>
|
|
|
|
<span class="k">if</span> <span class="n">kwargs</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">kwargs_param</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># Process our '**kwargs'-like parameter</span>
|
|
<span class="n">arguments</span><span class="p">[</span><span class="n">kwargs_param</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">kwargs</span>
|
|
<span class="k">elif</span> <span class="n">pos_only_param_in_kwargs</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s1">'got some positional-only arguments passed as '</span>
|
|
<span class="s1">'keyword arguments: </span><span class="si">{arg!r}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
|
<span class="n">arg</span><span class="o">=</span><span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
|
|
<span class="n">param</span><span class="o">.</span><span class="n">name</span>
|
|
<span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">pos_only_param_in_kwargs</span>
|
|
<span class="p">),</span>
|
|
<span class="p">),</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s1">'got an unexpected keyword argument </span><span class="si">{arg!r}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
|
<span class="n">arg</span><span class="o">=</span><span class="nb">next</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">kwargs</span><span class="p">))))</span>
|
|
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_bound_arguments_cls</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arguments</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">bind</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get a BoundArguments object, that maps the passed `args`</span>
|
|
<span class="sd"> and `kwargs` to the function's signature. Raises `TypeError`</span>
|
|
<span class="sd"> if the passed arguments can not be bound.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_bind</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">bind_partial</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get a BoundArguments object, that partially maps the</span>
|
|
<span class="sd"> passed `args` and `kwargs` to the function's signature.</span>
|
|
<span class="sd"> Raises `TypeError` if the passed arguments can not be bound.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_bind</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="n">partial</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span>
|
|
<span class="p">(</span><span class="nb">tuple</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_parameters</span><span class="o">.</span><span class="n">values</span><span class="p">()),),</span>
|
|
<span class="p">{</span><span class="s1">'_return_annotation'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_return_annotation</span><span class="p">})</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__setstate__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">state</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_return_annotation</span> <span class="o">=</span> <span class="n">state</span><span class="p">[</span><span class="s1">'_return_annotation'</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="s1">'<</span><span class="si">{}</span><span class="s1"> </span><span class="si">{}</span><span class="s1">>'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">format</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">format</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">max_width</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Create a string representation of the Signature object.</span>
|
|
|
|
<span class="sd"> If *max_width* integer is passed,</span>
|
|
<span class="sd"> signature will try to fit into the *max_width*.</span>
|
|
<span class="sd"> If signature is longer than *max_width*,</span>
|
|
<span class="sd"> all parameters will be on separate lines.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">render_pos_only_separator</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="n">render_kw_only_separator</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
|
|
<span class="n">formatted</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">param</span><span class="p">)</span>
|
|
|
|
<span class="n">kind</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="n">kind</span>
|
|
|
|
<span class="k">if</span> <span class="n">kind</span> <span class="o">==</span> <span class="n">_POSITIONAL_ONLY</span><span class="p">:</span>
|
|
<span class="n">render_pos_only_separator</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">elif</span> <span class="n">render_pos_only_separator</span><span class="p">:</span>
|
|
<span class="c1"># It's not a positional-only parameter, and the flag</span>
|
|
<span class="c1"># is set to 'True' (there were pos-only params before.)</span>
|
|
<span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)</span>
|
|
<span class="n">render_pos_only_separator</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="k">if</span> <span class="n">kind</span> <span class="o">==</span> <span class="n">_VAR_POSITIONAL</span><span class="p">:</span>
|
|
<span class="c1"># OK, we have an '*args'-like parameter, so we won't need</span>
|
|
<span class="c1"># a '*' to separate keyword-only arguments</span>
|
|
<span class="n">render_kw_only_separator</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="k">elif</span> <span class="n">kind</span> <span class="o">==</span> <span class="n">_KEYWORD_ONLY</span> <span class="ow">and</span> <span class="n">render_kw_only_separator</span><span class="p">:</span>
|
|
<span class="c1"># We have a keyword-only parameter to render and we haven't</span>
|
|
<span class="c1"># rendered an '*args'-like parameter before, so add a '*'</span>
|
|
<span class="c1"># separator to the parameters list ("foo(arg1, *, arg2)" case)</span>
|
|
<span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'*'</span><span class="p">)</span>
|
|
<span class="c1"># This condition should be only triggered once, so</span>
|
|
<span class="c1"># reset the flag</span>
|
|
<span class="n">render_kw_only_separator</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">formatted</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">render_pos_only_separator</span><span class="p">:</span>
|
|
<span class="c1"># There were only positional-only parameters, hence the</span>
|
|
<span class="c1"># flag was not reset to 'False'</span>
|
|
<span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)</span>
|
|
|
|
<span class="n">rendered</span> <span class="o">=</span> <span class="s1">'(</span><span class="si">{}</span><span class="s1">)'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">result</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">max_width</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">rendered</span><span class="p">)</span> <span class="o">></span> <span class="n">max_width</span><span class="p">:</span>
|
|
<span class="n">rendered</span> <span class="o">=</span> <span class="s1">'(</span><span class="se">\n</span><span class="s1"> </span><span class="si">{}</span><span class="se">\n</span><span class="s1">)'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="s1">',</span><span class="se">\n</span><span class="s1"> '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">result</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">return_annotation</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_empty</span><span class="p">:</span>
|
|
<span class="n">anno</span> <span class="o">=</span> <span class="n">formatannotation</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">return_annotation</span><span class="p">)</span>
|
|
<span class="n">rendered</span> <span class="o">+=</span> <span class="s1">' -> </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">anno</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">rendered</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">signature</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">follow_wrapped</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="nb">globals</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="nb">locals</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">eval_str</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Get a signature object for the passed callable."""</span>
|
|
<span class="k">return</span> <span class="n">Signature</span><span class="o">.</span><span class="n">from_callable</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">follow_wrapped</span><span class="o">=</span><span class="n">follow_wrapped</span><span class="p">,</span>
|
|
<span class="nb">globals</span><span class="o">=</span><span class="nb">globals</span><span class="p">,</span> <span class="nb">locals</span><span class="o">=</span><span class="nb">locals</span><span class="p">,</span> <span class="n">eval_str</span><span class="o">=</span><span class="n">eval_str</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">BufferFlags</span><span class="p">(</span><span class="n">enum</span><span class="o">.</span><span class="n">IntFlag</span><span class="p">):</span>
|
|
<span class="n">SIMPLE</span> <span class="o">=</span> <span class="mh">0x0</span>
|
|
<span class="n">WRITABLE</span> <span class="o">=</span> <span class="mh">0x1</span>
|
|
<span class="n">FORMAT</span> <span class="o">=</span> <span class="mh">0x4</span>
|
|
<span class="n">ND</span> <span class="o">=</span> <span class="mh">0x8</span>
|
|
<span class="n">STRIDES</span> <span class="o">=</span> <span class="mh">0x10</span> <span class="o">|</span> <span class="n">ND</span>
|
|
<span class="n">C_CONTIGUOUS</span> <span class="o">=</span> <span class="mh">0x20</span> <span class="o">|</span> <span class="n">STRIDES</span>
|
|
<span class="n">F_CONTIGUOUS</span> <span class="o">=</span> <span class="mh">0x40</span> <span class="o">|</span> <span class="n">STRIDES</span>
|
|
<span class="n">ANY_CONTIGUOUS</span> <span class="o">=</span> <span class="mh">0x80</span> <span class="o">|</span> <span class="n">STRIDES</span>
|
|
<span class="n">INDIRECT</span> <span class="o">=</span> <span class="mh">0x100</span> <span class="o">|</span> <span class="n">STRIDES</span>
|
|
<span class="n">CONTIG</span> <span class="o">=</span> <span class="n">ND</span> <span class="o">|</span> <span class="n">WRITABLE</span>
|
|
<span class="n">CONTIG_RO</span> <span class="o">=</span> <span class="n">ND</span>
|
|
<span class="n">STRIDED</span> <span class="o">=</span> <span class="n">STRIDES</span> <span class="o">|</span> <span class="n">WRITABLE</span>
|
|
<span class="n">STRIDED_RO</span> <span class="o">=</span> <span class="n">STRIDES</span>
|
|
<span class="n">RECORDS</span> <span class="o">=</span> <span class="n">STRIDES</span> <span class="o">|</span> <span class="n">WRITABLE</span> <span class="o">|</span> <span class="n">FORMAT</span>
|
|
<span class="n">RECORDS_RO</span> <span class="o">=</span> <span class="n">STRIDES</span> <span class="o">|</span> <span class="n">FORMAT</span>
|
|
<span class="n">FULL</span> <span class="o">=</span> <span class="n">INDIRECT</span> <span class="o">|</span> <span class="n">WRITABLE</span> <span class="o">|</span> <span class="n">FORMAT</span>
|
|
<span class="n">FULL_RO</span> <span class="o">=</span> <span class="n">INDIRECT</span> <span class="o">|</span> <span class="n">FORMAT</span>
|
|
<span class="n">READ</span> <span class="o">=</span> <span class="mh">0x100</span>
|
|
<span class="n">WRITE</span> <span class="o">=</span> <span class="mh">0x200</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_main</span><span class="p">():</span>
|
|
<span class="w"> </span><span class="sd">""" Logic for inspecting an object given at command line """</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">argparse</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">importlib</span>
|
|
|
|
<span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">()</span>
|
|
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
|
<span class="s1">'object'</span><span class="p">,</span>
|
|
<span class="n">help</span><span class="o">=</span><span class="s2">"The object to be analysed. "</span>
|
|
<span class="s2">"It supports the 'module:qualname' syntax"</span><span class="p">)</span>
|
|
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
|
<span class="s1">'-d'</span><span class="p">,</span> <span class="s1">'--details'</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s1">'store_true'</span><span class="p">,</span>
|
|
<span class="n">help</span><span class="o">=</span><span class="s1">'Display info about the module rather than its source code'</span><span class="p">)</span>
|
|
|
|
<span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span>
|
|
|
|
<span class="n">target</span> <span class="o">=</span> <span class="n">args</span><span class="o">.</span><span class="n">object</span>
|
|
<span class="n">mod_name</span><span class="p">,</span> <span class="n">has_attrs</span><span class="p">,</span> <span class="n">attrs</span> <span class="o">=</span> <span class="n">target</span><span class="o">.</span><span class="n">partition</span><span class="p">(</span><span class="s2">":"</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="n">module</span> <span class="o">=</span> <span class="n">importlib</span><span class="o">.</span><span class="n">import_module</span><span class="p">(</span><span class="n">mod_name</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s2">"Failed to import </span><span class="si">{}</span><span class="s2"> (</span><span class="si">{}</span><span class="s2">: </span><span class="si">{}</span><span class="s2">)"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mod_name</span><span class="p">,</span>
|
|
<span class="nb">type</span><span class="p">(</span><span class="n">exc</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
|
|
<span class="n">exc</span><span class="p">)</span>
|
|
<span class="nb">print</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
|
|
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">has_attrs</span><span class="p">:</span>
|
|
<span class="n">parts</span> <span class="o">=</span> <span class="n">attrs</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"."</span><span class="p">)</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="n">module</span>
|
|
<span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">parts</span><span class="p">:</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">part</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">module</span><span class="o">.</span><span class="vm">__name__</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">builtin_module_names</span><span class="p">:</span>
|
|
<span class="nb">print</span><span class="p">(</span><span class="s2">"Can't get info for builtin modules."</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
|
|
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">details</span><span class="p">:</span>
|
|
<span class="nb">print</span><span class="p">(</span><span class="s1">'Target: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">target</span><span class="p">))</span>
|
|
<span class="nb">print</span><span class="p">(</span><span class="s1">'Origin: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">getsourcefile</span><span class="p">(</span><span class="n">module</span><span class="p">)))</span>
|
|
<span class="nb">print</span><span class="p">(</span><span class="s1">'Cached: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">module</span><span class="o">.</span><span class="n">__cached__</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">obj</span> <span class="ow">is</span> <span class="n">module</span><span class="p">:</span>
|
|
<span class="nb">print</span><span class="p">(</span><span class="s1">'Loader: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="n">module</span><span class="o">.</span><span class="n">__loader__</span><span class="p">)))</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="s1">'__path__'</span><span class="p">):</span>
|
|
<span class="nb">print</span><span class="p">(</span><span class="s1">'Submodule search path: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">module</span><span class="o">.</span><span class="n">__path__</span><span class="p">))</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">__</span><span class="p">,</span> <span class="n">lineno</span> <span class="o">=</span> <span class="n">findsource</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="nb">print</span><span class="p">(</span><span class="s1">'Line: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">lineno</span><span class="p">))</span>
|
|
|
|
<span class="nb">print</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="nb">print</span><span class="p">(</span><span class="n">getsource</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
|
|
|
|
|
|
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
|
|
<span class="n">_main</span><span class="p">()</span>
|
|
</pre></div>
|
|
|
|
<div class="clearer"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sphinxsidebar" role="navigation" aria-label="Main">
|
|
<div class="sphinxsidebarwrapper">
|
|
<p class="logo"><a href="../index.html">
|
|
<img class="logo" src="../_static/evennia_logo.png" alt="Logo of Evennia"/>
|
|
</a></p>
|
|
<search id="searchbox" style="display: none" role="search">
|
|
<h3 id="searchlabel">Quick search</h3>
|
|
<div class="searchformwrapper">
|
|
<form class="search" action="../search.html" method="get">
|
|
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
|
<input type="submit" value="Go" />
|
|
</form>
|
|
</div>
|
|
</search>
|
|
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Links</h3>
|
|
<ul>
|
|
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
|
|
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
|
|
<li><a href="https://github.com/evennia/evennia">Github</a> </li>
|
|
<li><a href="http://games.evennia.com">Game Index</a> </li>
|
|
<li>
|
|
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
|
|
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
|
|
<a href="https://evennia.blogspot.com/">Blog</a>
|
|
</li>
|
|
</ul>
|
|
<h3>Doc Versions</h3>
|
|
<ul>
|
|
|
|
<li>
|
|
<a href="https://www.evennia.com/docs/latest/index.html">latest (main branch)</a>
|
|
</li>
|
|
|
|
|
|
<li>
|
|
<a href="https://www.evennia.com/docs/5.x/index.html">v5.0.0 branch (outdated)</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="https://www.evennia.com/docs/4.x/index.html">v4.0.0 branch (outdated)</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="https://www.evennia.com/docs/3.x/index.html">v3.0.0 branch (outdated)</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="https://www.evennia.com/docs/2.x/index.html">v2.0.0 branch (outdated)</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="https://www.evennia.com/docs/1.x/index.html">v1.0.0 branch (outdated)</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="https://www.evennia.com/docs/0.x/index.html">v0.9.5 branch (outdated)</a>
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
</div>
|
|
<div class="clearer"></div>
|
|
</div>
|
|
<div class="related" role="navigation" aria-label="Related">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../genindex.html" title="General Index"
|
|
>index</a></li>
|
|
<li class="right" >
|
|
<a href="../py-modindex.html" title="Python Module Index"
|
|
>modules</a> |</li>
|
|
<li class="nav-item nav-item-0"><a href="../index.html">Evennia</a> »</li>
|
|
<li class="nav-item nav-item-1"><a href="index.html" >Module code</a> »</li>
|
|
<li class="nav-item nav-item-this"><a href="">inspect</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="footer" role="contentinfo">
|
|
© Copyright 2024, The Evennia developer community.
|
|
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
|
|
</div>
|
|
</body>
|
|
</html> |