mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
2313 lines
No EOL
328 KiB
HTML
2313 lines
No EOL
328 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>enum — 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="">enum</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="document">
|
|
<div class="documentwrapper">
|
|
<div class="bodywrapper">
|
|
<div class="body" role="main">
|
|
|
|
<h1>Source code for enum</h1><div class="highlight"><pre>
|
|
<span></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">builtins</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">bltns</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">functools</span><span class="w"> </span><span class="kn">import</span> <span class="n">partial</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">types</span><span class="w"> </span><span class="kn">import</span> <span class="n">MappingProxyType</span><span class="p">,</span> <span class="n">DynamicClassAttribute</span>
|
|
|
|
|
|
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="s1">'EnumType'</span><span class="p">,</span> <span class="s1">'EnumMeta'</span><span class="p">,</span> <span class="s1">'EnumDict'</span><span class="p">,</span>
|
|
<span class="s1">'Enum'</span><span class="p">,</span> <span class="s1">'IntEnum'</span><span class="p">,</span> <span class="s1">'StrEnum'</span><span class="p">,</span> <span class="s1">'Flag'</span><span class="p">,</span> <span class="s1">'IntFlag'</span><span class="p">,</span> <span class="s1">'ReprEnum'</span><span class="p">,</span>
|
|
<span class="s1">'auto'</span><span class="p">,</span> <span class="s1">'unique'</span><span class="p">,</span> <span class="s1">'property'</span><span class="p">,</span> <span class="s1">'verify'</span><span class="p">,</span> <span class="s1">'member'</span><span class="p">,</span> <span class="s1">'nonmember'</span><span class="p">,</span>
|
|
<span class="s1">'FlagBoundary'</span><span class="p">,</span> <span class="s1">'STRICT'</span><span class="p">,</span> <span class="s1">'CONFORM'</span><span class="p">,</span> <span class="s1">'EJECT'</span><span class="p">,</span> <span class="s1">'KEEP'</span><span class="p">,</span>
|
|
<span class="s1">'global_flag_repr'</span><span class="p">,</span> <span class="s1">'global_enum_repr'</span><span class="p">,</span> <span class="s1">'global_str'</span><span class="p">,</span> <span class="s1">'global_enum'</span><span class="p">,</span>
|
|
<span class="s1">'EnumCheck'</span><span class="p">,</span> <span class="s1">'CONTINUOUS'</span><span class="p">,</span> <span class="s1">'NAMED_FLAGS'</span><span class="p">,</span> <span class="s1">'UNIQUE'</span><span class="p">,</span>
|
|
<span class="s1">'pickle_by_global_name'</span><span class="p">,</span> <span class="s1">'pickle_by_enum_name'</span><span class="p">,</span>
|
|
<span class="p">]</span>
|
|
|
|
|
|
<span class="c1"># Dummy value for Enum and Flag as there are explicit checks for them</span>
|
|
<span class="c1"># before they have been created.</span>
|
|
<span class="c1"># This is also why there are checks in EnumType like `if Enum is not None`</span>
|
|
<span class="n">Enum</span> <span class="o">=</span> <span class="n">Flag</span> <span class="o">=</span> <span class="n">EJECT</span> <span class="o">=</span> <span class="n">_stdlib_enums</span> <span class="o">=</span> <span class="n">ReprEnum</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">nonmember</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Protects item from becoming an Enum member during class creation.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">member</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Forces item to become an Enum member during class creation.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_is_descriptor</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Returns True if obj is a descriptor, False otherwise.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">partial</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span>
|
|
<span class="nb">hasattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__get__'</span><span class="p">)</span> <span class="ow">or</span>
|
|
<span class="nb">hasattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__set__'</span><span class="p">)</span> <span class="ow">or</span>
|
|
<span class="nb">hasattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__delete__'</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_is_dunder</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Returns True if a __dunder__ name, False otherwise.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="nb">len</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">></span> <span class="mi">4</span> <span class="ow">and</span>
|
|
<span class="n">name</span><span class="p">[:</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="n">name</span><span class="p">[</span><span class="o">-</span><span class="mi">2</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">2</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="o">-</span><span class="mi">3</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'_'</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_is_sunder</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Returns True if a _sunder_ name, False otherwise.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="nb">len</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">></span> <span class="mi">2</span> <span class="ow">and</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="n">name</span><span class="p">[</span><span class="o">-</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">name</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">name</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'_'</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_is_internal_class</span><span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
|
|
<span class="c1"># do not use `re` as `re` imports `enum`</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
<span class="n">qualname</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">'__qualname__'</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span>
|
|
<span class="n">s_pattern</span> <span class="o">=</span> <span class="n">cls_name</span> <span class="o">+</span> <span class="s1">'.'</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="s1">''</span><span class="p">)</span>
|
|
<span class="n">e_pattern</span> <span class="o">=</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="n">s_pattern</span>
|
|
<span class="k">return</span> <span class="n">qualname</span> <span class="o">==</span> <span class="n">s_pattern</span> <span class="ow">or</span> <span class="n">qualname</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">e_pattern</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_is_private</span><span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
|
|
<span class="c1"># do not use `re` as `re` imports `enum`</span>
|
|
<span class="n">pattern</span> <span class="o">=</span> <span class="s1">'_</span><span class="si">%s</span><span class="s1">__'</span> <span class="o">%</span> <span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="p">)</span>
|
|
<span class="n">pat_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="nb">len</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">></span> <span class="n">pat_len</span>
|
|
<span class="ow">and</span> <span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="p">(</span><span class="n">name</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'_'</span> <span class="ow">or</span> <span class="n">name</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'_'</span><span class="p">)</span>
|
|
<span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_is_single_bit</span><span class="p">(</span><span class="n">num</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> True if only one bit set in num (should be an int)</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">num</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
<span class="n">num</span> <span class="o">&=</span> <span class="n">num</span> <span class="o">-</span> <span class="mi">1</span>
|
|
<span class="k">return</span> <span class="n">num</span> <span class="o">==</span> <span class="mi">0</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_make_class_unpicklable</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Make the given obj un-picklable.</span>
|
|
|
|
<span class="sd"> obj should be either a dictionary, or an Enum</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_break_on_call_reduce</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proto</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"> cannot be pickled'</span> <span class="o">%</span> <span class="bp">self</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">dict</span><span class="p">):</span>
|
|
<span class="n">obj</span><span class="p">[</span><span class="s1">'__reduce_ex__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">_break_on_call_reduce</span>
|
|
<span class="n">obj</span><span class="p">[</span><span class="s1">'__module__'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'<unknown>'</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__reduce_ex__'</span><span class="p">,</span> <span class="n">_break_on_call_reduce</span><span class="p">)</span>
|
|
<span class="nb">setattr</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="s1">'<unknown>'</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_iter_bits_lsb</span><span class="p">(</span><span class="n">num</span><span class="p">):</span>
|
|
<span class="c1"># num must be a positive integer</span>
|
|
<span class="n">original</span> <span class="o">=</span> <span class="n">num</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="n">Enum</span><span class="p">):</span>
|
|
<span class="n">num</span> <span class="o">=</span> <span class="n">num</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">if</span> <span class="n">num</span> <span class="o"><</span> <span class="mi">0</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 positive integer'</span> <span class="o">%</span> <span class="n">original</span><span class="p">)</span>
|
|
<span class="k">while</span> <span class="n">num</span><span class="p">:</span>
|
|
<span class="n">b</span> <span class="o">=</span> <span class="n">num</span> <span class="o">&</span> <span class="p">(</span><span class="o">~</span><span class="n">num</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="k">yield</span> <span class="n">b</span>
|
|
<span class="n">num</span> <span class="o">^=</span> <span class="n">b</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">show_flag_values</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">_iter_bits_lsb</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">bin</span><span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="n">max_bits</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Like built-in bin(), except negative values are represented in</span>
|
|
<span class="sd"> twos-complement, and the leading bit always indicates sign</span>
|
|
<span class="sd"> (0=positive, 1=negative).</span>
|
|
|
|
<span class="sd"> >>> bin(10)</span>
|
|
<span class="sd"> '0b0 1010'</span>
|
|
<span class="sd"> >>> bin(~10) # ~10 is -11</span>
|
|
<span class="sd"> '0b1 0101'</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">num</span> <span class="o">=</span> <span class="n">num</span><span class="o">.</span><span class="fm">__index__</span><span class="p">()</span>
|
|
<span class="n">ceiling</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">**</span> <span class="p">(</span><span class="n">num</span><span class="p">)</span><span class="o">.</span><span class="n">bit_length</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="n">num</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="n">s</span> <span class="o">=</span> <span class="n">bltns</span><span class="o">.</span><span class="n">bin</span><span class="p">(</span><span class="n">num</span> <span class="o">+</span> <span class="n">ceiling</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'1'</span><span class="p">,</span> <span class="s1">'0'</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">s</span> <span class="o">=</span> <span class="n">bltns</span><span class="o">.</span><span class="n">bin</span><span class="p">(</span><span class="o">~</span><span class="n">num</span> <span class="o">^</span> <span class="p">(</span><span class="n">ceiling</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">ceiling</span><span class="p">)</span>
|
|
<span class="n">sign</span> <span class="o">=</span> <span class="n">s</span><span class="p">[:</span><span class="mi">3</span><span class="p">]</span>
|
|
<span class="n">digits</span> <span class="o">=</span> <span class="n">s</span><span class="p">[</span><span class="mi">3</span><span class="p">:]</span>
|
|
<span class="k">if</span> <span class="n">max_bits</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">digits</span><span class="p">)</span> <span class="o"><</span> <span class="n">max_bits</span><span class="p">:</span>
|
|
<span class="n">digits</span> <span class="o">=</span> <span class="p">(</span><span class="n">sign</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">max_bits</span> <span class="o">+</span> <span class="n">digits</span><span class="p">)[</span><span class="o">-</span><span class="n">max_bits</span><span class="p">:]</span>
|
|
<span class="k">return</span> <span class="s2">"</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">sign</span><span class="p">,</span> <span class="n">digits</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_dedent</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Like textwrap.dedent. Rewritten because we cannot import textwrap.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">lines</span> <span class="o">=</span> <span class="n">text</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">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">ch</span> <span class="ow">in</span> <span class="nb">enumerate</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="k">if</span> <span class="n">ch</span> <span class="o">!=</span> <span class="s1">' '</span><span class="p">:</span>
|
|
<span class="k">break</span>
|
|
<span class="k">for</span> <span class="n">j</span><span class="p">,</span> <span class="n">l</span> <span class="ow">in</span> <span class="nb">enumerate</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">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">l</span><span class="p">[</span><span class="n">i</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">class</span><span class="w"> </span><span class="nc">_not_given</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="p">(</span><span class="s1">'<not given>'</span><span class="p">)</span>
|
|
<span class="n">_not_given</span> <span class="o">=</span> <span class="n">_not_given</span><span class="p">()</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_auto_null</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">'_auto_null'</span>
|
|
<span class="n">_auto_null</span> <span class="o">=</span> <span class="n">_auto_null</span><span class="p">()</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">auto</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Instances are replaced with an appropriate value in Enum class suites.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="n">_auto_null</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="s2">"auto(</span><span class="si">%r</span><span class="s2">)"</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">property</span><span class="p">(</span><span class="n">DynamicClassAttribute</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> This is a descriptor, used to define attributes that act differently</span>
|
|
<span class="sd"> when accessed through an enum member and through an enum class.</span>
|
|
<span class="sd"> Instance access is the same as property(), but access to an attribute</span>
|
|
<span class="sd"> through the enum class will instead look in the class' _member_map_ for</span>
|
|
<span class="sd"> a corresponding enum member.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">member</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">_attr_type</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">_cls_type</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__get__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">ownerclass</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">instance</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">member</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="bp">self</span><span class="o">.</span><span class="n">member</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span>
|
|
<span class="s1">'</span><span class="si">%r</span><span class="s1"> has no attribute </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">ownerclass</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="p">)</span>
|
|
<span class="k">if</span> <span class="bp">self</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="c1"># use previous enum.property</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">fget</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_attr_type</span> <span class="o">==</span> <span class="s1">'attr'</span><span class="p">:</span>
|
|
<span class="c1"># look up previous attibute</span>
|
|
<span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_cls_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_attr_type</span> <span class="o">==</span> <span class="s1">'desc'</span><span class="p">:</span>
|
|
<span class="c1"># use previous descriptor</span>
|
|
<span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">instance</span><span class="o">.</span><span class="n">_value_</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="c1"># look for a member by this name.</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">ownerclass</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span>
|
|
<span class="s1">'</span><span class="si">%r</span><span class="s1"> has no attribute </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">ownerclass</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="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__set__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fset</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="bp">self</span><span class="o">.</span><span class="n">fset</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span>
|
|
<span class="s2">"<enum </span><span class="si">%r</span><span class="s2">> cannot set attribute </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">clsname</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="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__delete__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fdel</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="bp">self</span><span class="o">.</span><span class="n">fdel</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span>
|
|
<span class="s2">"<enum </span><span class="si">%r</span><span class="s2">> cannot delete attribute </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">clsname</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="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__set_name__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ownerclass</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="bp">self</span><span class="o">.</span><span class="n">clsname</span> <span class="o">=</span> <span class="n">ownerclass</span><span class="o">.</span><span class="vm">__name__</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_proto_member</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> intermediate step for enum members between class execution and final creation</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__set_name__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">enum_class</span><span class="p">,</span> <span class="n">member_name</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> convert each quasi-member into an instance of the new enum class</span>
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># first step: remove ourself from enum_class</span>
|
|
<span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">member_name</span><span class="p">)</span>
|
|
<span class="c1"># second step: create member based on enum_class</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</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">value</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="k">if</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="nb">tuple</span><span class="p">:</span> <span class="c1"># special case for tuple enums</span>
|
|
<span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="p">)</span> <span class="c1"># wrap it one more time</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_use_args_</span><span class="p">:</span>
|
|
<span class="n">enum_member</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_new_member_</span><span class="p">(</span><span class="n">enum_class</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">enum_member</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_new_member_</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">enum_member</span><span class="p">,</span> <span class="s1">'_value_'</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span>
|
|
<span class="n">enum_member</span><span class="o">.</span><span class="n">_value_</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">enum_member</span><span class="o">.</span><span class="n">_value_</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_type_</span><span class="p">(</span><span class="o">*</span><span class="n">args</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">new_exc</span> <span class="o">=</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s1">'_value_ not set in __new__, unable to create it'</span>
|
|
<span class="p">)</span>
|
|
<span class="n">new_exc</span><span class="o">.</span><span class="n">__cause__</span> <span class="o">=</span> <span class="n">exc</span>
|
|
<span class="k">raise</span> <span class="n">new_exc</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">enum_member</span><span class="o">.</span><span class="n">_value_</span>
|
|
<span class="n">enum_member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">=</span> <span class="n">member_name</span>
|
|
<span class="n">enum_member</span><span class="o">.</span><span class="vm">__objclass__</span> <span class="o">=</span> <span class="n">enum_class</span>
|
|
<span class="n">enum_member</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
|
|
<span class="n">enum_member</span><span class="o">.</span><span class="n">_sort_order_</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">enum_class</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_flag_mask_</span> <span class="o">|=</span> <span class="n">value</span>
|
|
<span class="k">if</span> <span class="n">_is_single_bit</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_singles_mask_</span> <span class="o">|=</span> <span class="n">value</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_all_bits_</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">**</span> <span class="p">((</span><span class="n">enum_class</span><span class="o">.</span><span class="n">_flag_mask_</span><span class="p">)</span><span class="o">.</span><span class="n">bit_length</span><span class="p">())</span> <span class="o">-</span> <span class="mi">1</span>
|
|
|
|
<span class="c1"># If another member with the same value was already defined, the</span>
|
|
<span class="c1"># new member becomes an alias to the existing one.</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># try to do a fast lookup to avoid the quadratic loop</span>
|
|
<span class="n">enum_member</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">[</span><span class="n">value</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">canonical_member</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">canonical_member</span><span class="o">.</span><span class="n">_value_</span> <span class="o">==</span> <span class="n">value</span><span class="p">:</span>
|
|
<span class="n">enum_member</span> <span class="o">=</span> <span class="n">canonical_member</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">KeyError</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="c1"># this could still be an alias if the value is multi-bit and the</span>
|
|
<span class="c1"># class is a flag class</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="n">Flag</span> <span class="ow">is</span> <span class="kc">None</span>
|
|
<span class="ow">or</span> <span class="ow">not</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">)</span>
|
|
<span class="p">):</span>
|
|
<span class="c1"># no other instances found, record this member in _member_names_</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_member_names_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">member_name</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="p">(</span>
|
|
<span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
|
|
<span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">int</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="n">_is_single_bit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="p">):</span>
|
|
<span class="c1"># no other instances found, record this member in _member_names_</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_member_names_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">member_name</span><span class="p">)</span>
|
|
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_add_member_</span><span class="p">(</span><span class="n">member_name</span><span class="p">,</span> <span class="n">enum_member</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># This may fail if value is not hashable. We can't add the value</span>
|
|
<span class="c1"># to the map, and by-value lookups for this value will be</span>
|
|
<span class="c1"># linear.</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">enum_member</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_hashable_values_</span><span class="p">:</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_hashable_values_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="c1"># keep track of the value in a list so containment checks are quick</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_unhashable_values_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_unhashable_values_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">member_name</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">EnumDict</span><span class="p">(</span><span class="nb">dict</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Track enum member order and ensure member names are not reused.</span>
|
|
|
|
<span class="sd"> EnumType will use the names found in self._member_names as the</span>
|
|
<span class="sd"> enumeration member names.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cls_name</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_member_names</span> <span class="o">=</span> <span class="p">{}</span> <span class="c1"># use a dict -- faster look-up than a list, and keeps insertion order since 3.7</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_last_values</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_ignore</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_auto_called</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_cls_name</span> <span class="o">=</span> <span class="n">cls_name</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__setitem__</span><span class="p">(</span><span class="bp">self</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="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Changes anything not dundered or not a descriptor.</span>
|
|
|
|
<span class="sd"> If an enum member name is used twice, an error is raised; duplicate</span>
|
|
<span class="sd"> values are not checked for.</span>
|
|
|
|
<span class="sd"> Single underscore (sunder) names are reserved.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cls_name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">_is_private</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_cls_name</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
|
|
<span class="c1"># do nothing, name will be a normal attribute</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">elif</span> <span class="n">_is_sunder</span><span class="p">(</span><span class="n">key</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span>
|
|
<span class="s1">'_order_'</span><span class="p">,</span>
|
|
<span class="s1">'_generate_next_value_'</span><span class="p">,</span> <span class="s1">'_numeric_repr_'</span><span class="p">,</span> <span class="s1">'_missing_'</span><span class="p">,</span> <span class="s1">'_ignore_'</span><span class="p">,</span>
|
|
<span class="s1">'_iter_member_'</span><span class="p">,</span> <span class="s1">'_iter_member_by_value_'</span><span class="p">,</span> <span class="s1">'_iter_member_by_def_'</span><span class="p">,</span>
|
|
<span class="s1">'_add_alias_'</span><span class="p">,</span> <span class="s1">'_add_value_alias_'</span><span class="p">,</span>
|
|
<span class="c1"># While not in use internally, those are common for pretty</span>
|
|
<span class="c1"># printing and thus excluded from Enum's reservation of</span>
|
|
<span class="c1"># _sunder_ names</span>
|
|
<span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'_repr_'</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
|
<span class="s1">'_sunder_ names, such as </span><span class="si">%r</span><span class="s1">, are reserved for future Enum use'</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s1">'_generate_next_value_'</span><span class="p">:</span>
|
|
<span class="c1"># check if members already defined as auto()</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_auto_called</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"_generate_next_value_ must be defined before members"</span><span class="p">)</span>
|
|
<span class="n">_gnv</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="vm">__func__</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">staticmethod</span><span class="p">)</span> <span class="k">else</span> <span class="n">value</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'_generate_next_value'</span><span class="p">,</span> <span class="n">_gnv</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s1">'_ignore_'</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span><span class="s1">' '</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_ignore</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="n">already</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="o">&</span> <span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_member_names</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">already</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
|
<span class="s1">'_ignore_ cannot specify already set names: </span><span class="si">%r</span><span class="s1">'</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">already</span><span class="p">,</span> <span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">_is_dunder</span><span class="p">(</span><span class="n">key</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s1">'__order__'</span><span class="p">:</span>
|
|
<span class="n">key</span> <span class="o">=</span> <span class="s1">'_order_'</span>
|
|
<span class="k">elif</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_member_names</span><span class="p">:</span>
|
|
<span class="c1"># descriptor overwriting an enum?</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"> already defined as </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="p">[</span><span class="n">key</span><span class="p">]))</span>
|
|
<span class="k">elif</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ignore</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">nonmember</span><span class="p">):</span>
|
|
<span class="c1"># unwrap value here; it won't be processed by the below `else`</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">partial</span><span class="p">):</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">warnings</span>
|
|
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s1">'functools.partial will be a method descriptor '</span>
|
|
<span class="s1">'in future Python versions; wrap it in '</span>
|
|
<span class="s1">'enum.member() if you want to preserve the '</span>
|
|
<span class="s1">'old behavior'</span><span class="p">,</span> <span class="ne">FutureWarning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">_is_descriptor</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cls_name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">_is_internal_class</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_cls_name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
|
<span class="c1"># do nothing, name will be a normal attribute</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
|
|
<span class="c1"># enum overwriting a descriptor?</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"> already defined as </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="p">[</span><span class="n">key</span><span class="p">]))</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">member</span><span class="p">):</span>
|
|
<span class="c1"># unwrap value here -- it will become a member</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="n">non_auto_store</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="n">single</span> <span class="o">=</span> <span class="kc">False</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="n">auto</span><span class="p">):</span>
|
|
<span class="n">single</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">any</span><span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">auto</span><span class="p">)</span> <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">value</span><span class="p">):</span>
|
|
<span class="c1"># insist on an actual tuple, no subclasses, in keeping with only supporting</span>
|
|
<span class="c1"># top-level auto() usage (not contained in any other data structure)</span>
|
|
<span class="n">auto_valued</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">t</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">value</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">auto</span><span class="p">):</span>
|
|
<span class="n">non_auto_store</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="k">if</span> <span class="n">v</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="n">_auto_null</span><span class="p">:</span>
|
|
<span class="n">v</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_generate_next_value</span><span class="p">(</span>
|
|
<span class="n">key</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="bp">self</span><span class="o">.</span><span class="n">_member_names</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_last_values</span><span class="p">[:],</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_auto_called</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="n">v</span> <span class="o">=</span> <span class="n">v</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_last_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
|
|
<span class="n">auto_valued</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">single</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">auto_valued</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># accepts iterable as multiple arguments?</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">t</span><span class="p">(</span><span class="n">auto_valued</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="c1"># then pass them in singly</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">t</span><span class="p">(</span><span class="o">*</span><span class="n">auto_valued</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_member_names</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="n">non_auto_store</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_last_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__setitem__</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="nd">@property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">member_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_member_names</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">members</span><span class="p">,</span> <span class="o">**</span><span class="n">more_members</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">members</span><span class="o">.</span><span class="n">keys</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="o">=</span> <span class="n">members</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">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">members</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="o">=</span> <span class="n">value</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">more_members</span><span class="o">.</span><span class="n">items</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="o">=</span> <span class="n">value</span>
|
|
|
|
<span class="n">_EnumDict</span> <span class="o">=</span> <span class="n">EnumDict</span> <span class="c1"># keep private name for backwards compatibility</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">EnumType</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Metaclass for Enum</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__prepare__</span><span class="p">(</span><span class="n">metacls</span><span class="p">,</span> <span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span>
|
|
<span class="c1"># check that previous enum members do not exist</span>
|
|
<span class="n">metacls</span><span class="o">.</span><span class="n">_check_for_existing_members_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span>
|
|
<span class="c1"># create the namespace dict</span>
|
|
<span class="n">enum_dict</span> <span class="o">=</span> <span class="n">EnumDict</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span>
|
|
<span class="c1"># inherit previous flags and _generate_next_value_ function</span>
|
|
<span class="n">member_type</span><span class="p">,</span> <span class="n">first_enum</span> <span class="o">=</span> <span class="n">metacls</span><span class="o">.</span><span class="n">_get_mixins_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">first_enum</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">enum_dict</span><span class="p">[</span><span class="s1">'_generate_next_value_'</span><span class="p">]</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span>
|
|
<span class="n">first_enum</span><span class="p">,</span> <span class="s1">'_generate_next_value_'</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">enum_dict</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="n">metacls</span><span class="p">,</span> <span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">classdict</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_simple</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span>
|
|
<span class="c1"># an Enum class is final once enumeration items have been defined; it</span>
|
|
<span class="c1"># cannot be mixed with other types (int, float, etc.) if it has an</span>
|
|
<span class="c1"># inherited __new__ unless a new __new__ is defined (or the resulting</span>
|
|
<span class="c1"># class will fail).</span>
|
|
<span class="c1">#</span>
|
|
<span class="k">if</span> <span class="n">_simple</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="n">metacls</span><span class="p">,</span> <span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">classdict</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">)</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># remove any keys listed in _ignore_</span>
|
|
<span class="n">classdict</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s1">'_ignore_'</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'_ignore_'</span><span class="p">)</span>
|
|
<span class="n">ignore</span> <span class="o">=</span> <span class="n">classdict</span><span class="p">[</span><span class="s1">'_ignore_'</span><span class="p">]</span>
|
|
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">ignore</span><span class="p">:</span>
|
|
<span class="n">classdict</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># grab member names</span>
|
|
<span class="n">member_names</span> <span class="o">=</span> <span class="n">classdict</span><span class="o">.</span><span class="n">_member_names</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># check for illegal enum names (any others?)</span>
|
|
<span class="n">invalid_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">member_names</span><span class="p">)</span> <span class="o">&</span> <span class="p">{</span><span class="s1">'mro'</span><span class="p">,</span> <span class="s1">''</span><span class="p">}</span>
|
|
<span class="k">if</span> <span class="n">invalid_names</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'invalid enum member name(s) </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span>
|
|
<span class="s1">','</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">invalid_names</span><span class="p">)</span>
|
|
<span class="p">))</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># adjust the sunders</span>
|
|
<span class="n">_order_</span> <span class="o">=</span> <span class="n">classdict</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">'_order_'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">_gnv</span> <span class="o">=</span> <span class="n">classdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'_generate_next_value_'</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">_gnv</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">type</span><span class="p">(</span><span class="n">_gnv</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">staticmethod</span><span class="p">:</span>
|
|
<span class="n">_gnv</span> <span class="o">=</span> <span class="nb">staticmethod</span><span class="p">(</span><span class="n">_gnv</span><span class="p">)</span>
|
|
<span class="c1"># convert to normal dict</span>
|
|
<span class="n">classdict</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">classdict</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
|
|
<span class="k">if</span> <span class="n">_gnv</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_generate_next_value_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">_gnv</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># data type of member and the controlling Enum class</span>
|
|
<span class="n">member_type</span><span class="p">,</span> <span class="n">first_enum</span> <span class="o">=</span> <span class="n">metacls</span><span class="o">.</span><span class="n">_get_mixins_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span>
|
|
<span class="fm">__new__</span><span class="p">,</span> <span class="n">save_new</span><span class="p">,</span> <span class="n">use_args</span> <span class="o">=</span> <span class="n">metacls</span><span class="o">.</span><span class="n">_find_new_</span><span class="p">(</span>
|
|
<span class="n">classdict</span><span class="p">,</span> <span class="n">member_type</span><span class="p">,</span> <span class="n">first_enum</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_new_member_'</span><span class="p">]</span> <span class="o">=</span> <span class="fm">__new__</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_use_args_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">use_args</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># convert future enum members into temporary _proto_members</span>
|
|
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">member_names</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">classdict</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">_proto_member</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># house-keeping structures</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_member_names_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_member_map_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_value2member_map_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_hashable_values_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># for comparing with non-hashable types</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_unhashable_values_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># e.g. frozenset() with set()</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_unhashable_values_map_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_member_type_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">member_type</span>
|
|
<span class="c1"># now set the __repr__ for the value</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_value_repr_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">metacls</span><span class="o">.</span><span class="n">_find_data_repr_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># Flag structures (will be removed if final class is not a Flag</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_boundary_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="n">boundary</span>
|
|
<span class="ow">or</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">first_enum</span><span class="p">,</span> <span class="s1">'_boundary_'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_flag_mask_'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_singles_mask_'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_all_bits_'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_inverted_'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_</span><span class="si">%s</span><span class="s1">__in_progress'</span> <span class="o">%</span> <span class="bp">cls</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="n">enum_class</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="n">metacls</span><span class="p">,</span> <span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">classdict</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">)</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'_</span><span class="si">%s</span><span class="s1">__in_progress'</span> <span class="o">%</span> <span class="bp">cls</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="s1">'_</span><span class="si">%s</span><span class="s1">__in_progress'</span> <span class="o">%</span> <span class="bp">cls</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
|
<span class="c1"># since 3.12 the note "Error calling __set_name__ on '_proto_member' instance ..."</span>
|
|
<span class="c1"># is tacked on to the error instead of raising a RuntimeError, so discard it</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="s1">'__notes__'</span><span class="p">):</span>
|
|
<span class="k">del</span> <span class="n">e</span><span class="o">.</span><span class="n">__notes__</span>
|
|
<span class="k">raise</span>
|
|
<span class="c1"># update classdict with any changes made by __init_subclass__</span>
|
|
<span class="n">classdict</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">enum_class</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">)</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># double check that repr and friends are not the mixin's or various</span>
|
|
<span class="c1"># things break (such as pickle)</span>
|
|
<span class="c1"># however, if the method is defined in the Enum itself, don't replace</span>
|
|
<span class="c1"># it</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># Also, special handling for ReprEnum</span>
|
|
<span class="k">if</span> <span class="n">ReprEnum</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">ReprEnum</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">member_type</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s1">'ReprEnum subclasses must be mixed with a data type (i.e.'</span>
|
|
<span class="s1">' int, str, float, etc.)'</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="s1">'__format__'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">classdict</span><span class="p">:</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="fm">__format__</span> <span class="o">=</span> <span class="n">member_type</span><span class="o">.</span><span class="fm">__format__</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'__format__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="fm">__format__</span>
|
|
<span class="k">if</span> <span class="s1">'__str__'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">classdict</span><span class="p">:</span>
|
|
<span class="n">method</span> <span class="o">=</span> <span class="n">member_type</span><span class="o">.</span><span class="fm">__str__</span>
|
|
<span class="k">if</span> <span class="n">method</span> <span class="ow">is</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__str__</span><span class="p">:</span>
|
|
<span class="c1"># if member_type does not define __str__, object.__str__ will use</span>
|
|
<span class="c1"># its __repr__ instead, so we'll also use its __repr__</span>
|
|
<span class="n">method</span> <span class="o">=</span> <span class="n">member_type</span><span class="o">.</span><span class="fm">__repr__</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="fm">__str__</span> <span class="o">=</span> <span class="n">method</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'__str__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="fm">__str__</span>
|
|
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'__repr__'</span><span class="p">,</span> <span class="s1">'__str__'</span><span class="p">,</span> <span class="s1">'__format__'</span><span class="p">,</span> <span class="s1">'__reduce_ex__'</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">classdict</span><span class="p">:</span>
|
|
<span class="c1"># check for mixin overrides before replacing</span>
|
|
<span class="n">enum_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">first_enum</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="n">found_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="n">object_method</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="n">data_type_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">member_type</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">found_method</span> <span class="ow">in</span> <span class="p">(</span><span class="n">data_type_method</span><span class="p">,</span> <span class="n">object_method</span><span class="p">):</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">enum_method</span><span class="p">)</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># for Flag, add __or__, __and__, __xor__, and __invert__</span>
|
|
<span class="k">if</span> <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span>
|
|
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">(</span>
|
|
<span class="s1">'__or__'</span><span class="p">,</span> <span class="s1">'__and__'</span><span class="p">,</span> <span class="s1">'__xor__'</span><span class="p">,</span>
|
|
<span class="s1">'__ror__'</span><span class="p">,</span> <span class="s1">'__rand__'</span><span class="p">,</span> <span class="s1">'__rxor__'</span><span class="p">,</span>
|
|
<span class="s1">'__invert__'</span>
|
|
<span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">classdict</span><span class="p">:</span>
|
|
<span class="n">enum_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">Flag</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">enum_method</span><span class="p">)</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">enum_method</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># replace any other __new__ with our own (as long as Enum is not None,</span>
|
|
<span class="c1"># anyway) -- again, this is to support pickle</span>
|
|
<span class="k">if</span> <span class="n">Enum</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># if the user defined their own __new__, save it before it gets</span>
|
|
<span class="c1"># clobbered in case they subclass later</span>
|
|
<span class="k">if</span> <span class="n">save_new</span><span class="p">:</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">__new_member__</span> <span class="o">=</span> <span class="fm">__new__</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="fm">__new__</span> <span class="o">=</span> <span class="n">Enum</span><span class="o">.</span><span class="fm">__new__</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># py3 support for definition order (helps keep py2/py3 code in sync)</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># _order_ checking is spread out into three/four steps</span>
|
|
<span class="c1"># - if enum_class is a Flag:</span>
|
|
<span class="c1"># - remove any non-single-bit flags from _order_</span>
|
|
<span class="c1"># - remove any aliases from _order_</span>
|
|
<span class="c1"># - check that _order_ and _member_names_ match</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># step 1: ensure we have a list</span>
|
|
<span class="k">if</span> <span class="n">_order_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">_order_</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="n">_order_</span> <span class="o">=</span> <span class="n">_order_</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span> <span class="s1">' '</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># remove Flag structures if final class is not a Flag</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="n">Flag</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="bp">cls</span> <span class="o">!=</span> <span class="s1">'Flag'</span>
|
|
<span class="ow">or</span> <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">)</span>
|
|
<span class="p">):</span>
|
|
<span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="s1">'_boundary_'</span><span class="p">)</span>
|
|
<span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="s1">'_flag_mask_'</span><span class="p">)</span>
|
|
<span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="s1">'_singles_mask_'</span><span class="p">)</span>
|
|
<span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="s1">'_all_bits_'</span><span class="p">)</span>
|
|
<span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="s1">'_inverted_'</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span>
|
|
<span class="c1"># set correct __iter__</span>
|
|
<span class="n">member_list</span> <span class="o">=</span> <span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">_value_</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">member_list</span> <span class="o">!=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">member_list</span><span class="p">):</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_iter_member_</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_iter_member_by_def_</span>
|
|
<span class="k">if</span> <span class="n">_order_</span><span class="p">:</span>
|
|
<span class="c1"># _order_ step 2: remove any items from _order_ that are not single-bit</span>
|
|
<span class="n">_order_</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">o</span>
|
|
<span class="k">for</span> <span class="n">o</span> <span class="ow">in</span> <span class="n">_order_</span>
|
|
<span class="k">if</span> <span class="n">o</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_map_</span> <span class="ow">or</span> <span class="n">_is_single_bit</span><span class="p">(</span><span class="n">enum_class</span><span class="p">[</span><span class="n">o</span><span class="p">]</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span>
|
|
<span class="p">]</span>
|
|
<span class="c1">#</span>
|
|
<span class="k">if</span> <span class="n">_order_</span><span class="p">:</span>
|
|
<span class="c1"># _order_ step 3: remove aliases from _order_</span>
|
|
<span class="n">_order_</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">o</span>
|
|
<span class="k">for</span> <span class="n">o</span> <span class="ow">in</span> <span class="n">_order_</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="n">o</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_map_</span>
|
|
<span class="ow">or</span>
|
|
<span class="p">(</span><span class="n">o</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_map_</span> <span class="ow">and</span> <span class="n">o</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">)</span>
|
|
<span class="p">)]</span>
|
|
<span class="c1"># _order_ step 4: verify that _order_ and _member_names_ match</span>
|
|
<span class="k">if</span> <span class="n">_order_</span> <span class="o">!=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s1">'member order does not match _order_:</span><span class="se">\n</span><span class="s1"> </span><span class="si">%r</span><span class="se">\n</span><span class="s1"> </span><span class="si">%r</span><span class="s1">'</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">enum_class</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">,</span> <span class="n">_order_</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="c1">#</span>
|
|
<span class="k">return</span> <span class="n">enum_class</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__bool__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> classes/types should always be True.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__call__</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">names</span><span class="o">=</span><span class="n">_not_given</span><span class="p">,</span> <span class="o">*</span><span class="n">values</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">qualname</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Either returns an existing member, or creates a new enum class.</span>
|
|
|
|
<span class="sd"> This method is used both when an enum class is given a value to match</span>
|
|
<span class="sd"> to an enumeration member (i.e. Color(3)) and for the functional API</span>
|
|
<span class="sd"> (i.e. Color = Enum('Color', names='RED GREEN BLUE')).</span>
|
|
|
|
<span class="sd"> The value lookup branch is chosen if the enum is final.</span>
|
|
|
|
<span class="sd"> When used for the functional API:</span>
|
|
|
|
<span class="sd"> `value` will be the name of the new class.</span>
|
|
|
|
<span class="sd"> `names` should be either a string of white-space/comma delimited names</span>
|
|
<span class="sd"> (values will start at `start`), or an iterator/mapping of name, value pairs.</span>
|
|
|
|
<span class="sd"> `module` should be set to the module this class is being created in;</span>
|
|
<span class="sd"> if it is not set, an attempt to find that module will be made, but if</span>
|
|
<span class="sd"> it fails the class will not be picklable.</span>
|
|
|
|
<span class="sd"> `qualname` should be set to the actual location this class can be found</span>
|
|
<span class="sd"> at in its module; by default it is set to the global scope. If this is</span>
|
|
<span class="sd"> not correct, unpickling will fail in some circumstances.</span>
|
|
|
|
<span class="sd"> `type`, if set, will be mixed in as the first base class.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span>
|
|
<span class="c1"># simple value lookup if members exist</span>
|
|
<span class="k">if</span> <span class="n">names</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_not_given</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">names</span><span class="p">)</span> <span class="o">+</span> <span class="n">values</span>
|
|
<span class="k">return</span> <span class="bp">cls</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="c1"># otherwise, functional API: we're creating a new Enum type</span>
|
|
<span class="k">if</span> <span class="n">names</span> <span class="ow">is</span> <span class="n">_not_given</span> <span class="ow">and</span> <span class="nb">type</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># no body? no data-type? possibly wrong usage</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">cls</span><span class="si">}</span><span class="s2"> has no members; specify `names=()` if you meant to create a new, empty, enum"</span>
|
|
<span class="p">)</span>
|
|
<span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_create_</span><span class="p">(</span>
|
|
<span class="n">class_name</span><span class="o">=</span><span class="n">value</span><span class="p">,</span>
|
|
<span class="n">names</span><span class="o">=</span><span class="kc">None</span> <span class="k">if</span> <span class="n">names</span> <span class="ow">is</span> <span class="n">_not_given</span> <span class="k">else</span> <span class="n">names</span><span class="p">,</span>
|
|
<span class="n">module</span><span class="o">=</span><span class="n">module</span><span class="p">,</span>
|
|
<span class="n">qualname</span><span class="o">=</span><span class="n">qualname</span><span class="p">,</span>
|
|
<span class="nb">type</span><span class="o">=</span><span class="nb">type</span><span class="p">,</span>
|
|
<span class="n">start</span><span class="o">=</span><span class="n">start</span><span class="p">,</span>
|
|
<span class="n">boundary</span><span class="o">=</span><span class="n">boundary</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__contains__</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="w"> </span><span class="sd">"""Return True if `value` is in `cls`.</span>
|
|
|
|
<span class="sd"> `value` is in `cls` if:</span>
|
|
<span class="sd"> 1) `value` is a member of `cls`, or</span>
|
|
<span class="sd"> 2) `value` is the value of one of the `cls`'s members.</span>
|
|
<span class="sd"> 3) `value` is a pseudo-member (flags)</span>
|
|
<span class="sd"> """</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="bp">cls</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
<span class="k">if</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">result</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_missing_</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="bp">cls</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="n">value</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_unhashable_values_</span> <span class="c1"># both structures are lists</span>
|
|
<span class="ow">or</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_hashable_values_</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__delattr__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">attr</span><span class="p">):</span>
|
|
<span class="c1"># nicer error message when someone tries to delete an attribute</span>
|
|
<span class="c1"># (see issue19025).</span>
|
|
<span class="k">if</span> <span class="n">attr</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2"> cannot delete member </span><span class="si">%r</span><span class="s2">."</span> <span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">attr</span><span class="p">))</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__delattr__</span><span class="p">(</span><span class="n">attr</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__dir__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="n">interesting</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span>
|
|
<span class="s1">'__class__'</span><span class="p">,</span> <span class="s1">'__contains__'</span><span class="p">,</span> <span class="s1">'__doc__'</span><span class="p">,</span> <span class="s1">'__getitem__'</span><span class="p">,</span>
|
|
<span class="s1">'__iter__'</span><span class="p">,</span> <span class="s1">'__len__'</span><span class="p">,</span> <span class="s1">'__members__'</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">,</span>
|
|
<span class="s1">'__name__'</span><span class="p">,</span> <span class="s1">'__qualname__'</span><span class="p">,</span>
|
|
<span class="p">]</span>
|
|
<span class="o">+</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_names_</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_new_member_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__new__</span><span class="p">:</span>
|
|
<span class="n">interesting</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s1">'__new__'</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__init_subclass__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">object</span><span class="o">.</span><span class="n">__init_subclass__</span><span class="p">:</span>
|
|
<span class="n">interesting</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s1">'__init_subclass__'</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">interesting</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># return whatever mixed-in data type has</span>
|
|
<span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="nb">dir</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_member_type_</span><span class="p">))</span> <span class="o">|</span> <span class="n">interesting</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Return the member matching `name`.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__iter__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Return members in definition order.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</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="bp">cls</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__len__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Return the number of members (no aliases)</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">)</span>
|
|
|
|
<span class="nd">@bltns</span><span class="o">.</span><span class="n">property</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__members__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Returns a mapping of member name->value.</span>
|
|
|
|
<span class="sd"> This mapping lists all enum members, including aliases. Note that this</span>
|
|
<span class="sd"> is a read-only view of the internal mapping.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">MappingProxyType</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</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">cls</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="s2">"<flag </span><span class="si">%r</span><span class="s2">>"</span> <span class="o">%</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="s2">"<enum </span><span class="si">%r</span><span class="s2">>"</span> <span class="o">%</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__reversed__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Return members in reverse definition order.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</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="nb">reversed</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__setattr__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Block attempts to reassign Enum members.</span>
|
|
|
|
<span class="sd"> A simple assignment to the class namespace only changes one of the</span>
|
|
<span class="sd"> several possible ways to get an Enum member from the Enum class,</span>
|
|
<span class="sd"> resulting in an inconsistent Enumeration.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">member_map</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'_member_map_'</span><span class="p">,</span> <span class="p">{})</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">member_map</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="s1">'cannot reassign member </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="p">))</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__setattr__</span><span class="p">(</span><span class="n">name</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">_create_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">class_name</span><span class="p">,</span> <span class="n">names</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">qualname</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Convenience method to create a new Enum class.</span>
|
|
|
|
<span class="sd"> `names` can be:</span>
|
|
|
|
<span class="sd"> * A string containing member names, separated either with spaces or</span>
|
|
<span class="sd"> commas. Values are incremented by 1 from `start`.</span>
|
|
<span class="sd"> * An iterable of member names. Values are incremented by 1 from `start`.</span>
|
|
<span class="sd"> * An iterable of (member name, value) pairs.</span>
|
|
<span class="sd"> * A mapping of member name -> value pairs.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">metacls</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__class__</span>
|
|
<span class="n">bases</span> <span class="o">=</span> <span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="p">)</span> <span class="k">if</span> <span class="nb">type</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</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="n">_</span><span class="p">,</span> <span class="n">first_enum</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_get_mixins_</span><span class="p">(</span><span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span>
|
|
<span class="n">classdict</span> <span class="o">=</span> <span class="n">metacls</span><span class="o">.</span><span class="fm">__prepare__</span><span class="p">(</span><span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span>
|
|
|
|
<span class="c1"># special processing needed for names?</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">names</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="n">names</span> <span class="o">=</span> <span class="n">names</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span> <span class="s1">' '</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">names</span><span class="p">,</span> <span class="p">(</span><span class="nb">tuple</span><span class="p">,</span> <span class="nb">list</span><span class="p">))</span> <span class="ow">and</span> <span class="n">names</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">names</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="n">original_names</span><span class="p">,</span> <span class="n">names</span> <span class="o">=</span> <span class="n">names</span><span class="p">,</span> <span class="p">[]</span>
|
|
<span class="n">last_values</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">count</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">original_names</span><span class="p">):</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">first_enum</span><span class="o">.</span><span class="n">_generate_next_value_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">start</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">last_values</span><span class="p">[:])</span>
|
|
<span class="n">last_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</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">name</span><span class="p">,</span> <span class="n">value</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">names</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">names</span> <span class="o">=</span> <span class="p">()</span>
|
|
|
|
<span class="c1"># Here, names is either an iterable of (name, value) or a mapping.</span>
|
|
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">names</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="n">member_name</span><span class="p">,</span> <span class="n">member_value</span> <span class="o">=</span> <span class="n">item</span><span class="p">,</span> <span class="n">names</span><span class="p">[</span><span class="n">item</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">member_name</span><span class="p">,</span> <span class="n">member_value</span> <span class="o">=</span> <span class="n">item</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="n">member_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">member_value</span>
|
|
|
|
<span class="k">if</span> <span class="n">module</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">module</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">_getframemodulename</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="c1"># Fall back on _getframe if _getframemodulename is missing</span>
|
|
<span class="k">try</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">_getframe</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">f_globals</span><span class="p">[</span><span class="s1">'__name__'</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">AttributeError</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">,</span> <span class="ne">KeyError</span><span class="p">):</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">if</span> <span class="n">module</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">_make_class_unpicklable</span><span class="p">(</span><span class="n">classdict</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'__module__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">module</span>
|
|
<span class="k">if</span> <span class="n">qualname</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">classdict</span><span class="p">[</span><span class="s1">'__qualname__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">qualname</span>
|
|
|
|
<span class="k">return</span> <span class="n">metacls</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="n">metacls</span><span class="p">,</span> <span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">classdict</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="n">boundary</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_convert_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">module</span><span class="p">,</span> <span class="nb">filter</span><span class="p">,</span> <span class="n">source</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">boundary</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">as_global</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Create a new Enum subclass that replaces a collection of global constants</span>
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># convert all constants from source (or module) that pass filter() to</span>
|
|
<span class="c1"># a new Enum called name, and export the enum and its members back to</span>
|
|
<span class="c1"># module;</span>
|
|
<span class="c1"># also, replace the __reduce_ex__ method so unpickling works in</span>
|
|
<span class="c1"># previous Python versions</span>
|
|
<span class="n">module_globals</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="n">module</span><span class="p">]</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="k">if</span> <span class="n">source</span><span class="p">:</span>
|
|
<span class="n">source</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">source</span> <span class="o">=</span> <span class="n">module_globals</span>
|
|
<span class="c1"># _value2member_map_ is populated in the same order every time</span>
|
|
<span class="c1"># for a consistent reverse mapping of number to name when there</span>
|
|
<span class="c1"># are multiple names for the same number.</span>
|
|
<span class="n">members</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">source</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="nb">filter</span><span class="p">(</span><span class="n">name</span><span class="p">)]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># sort by value</span>
|
|
<span class="n">members</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">t</span><span class="p">:</span> <span class="p">(</span><span class="n">t</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="c1"># unless some values aren't comparable, in which case sort by name</span>
|
|
<span class="n">members</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">t</span><span class="p">:</span> <span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
|
<span class="n">body</span> <span class="o">=</span> <span class="p">{</span><span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span> <span class="n">t</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">members</span><span class="p">}</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'__module__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">module</span>
|
|
<span class="n">tmp_cls</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="p">),</span> <span class="n">body</span><span class="p">)</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="n">_simple_enum</span><span class="p">(</span><span class="n">etype</span><span class="o">=</span><span class="bp">cls</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="n">boundary</span> <span class="ow">or</span> <span class="n">KEEP</span><span class="p">)(</span><span class="n">tmp_cls</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">as_global</span><span class="p">:</span>
|
|
<span class="n">global_enum</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__module__</span><span class="p">]</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">update</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">module_globals</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="bp">cls</span>
|
|
<span class="k">return</span> <span class="bp">cls</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_check_for_existing_members_</span><span class="p">(</span><span class="n">mcls</span><span class="p">,</span> <span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span>
|
|
<span class="k">for</span> <span class="n">chain</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">chain</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">EnumType</span><span class="p">)</span> <span class="ow">and</span> <span class="n">base</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s2">"<enum </span><span class="si">%r</span><span class="s2">> cannot extend </span><span class="si">%r</span><span class="s2">"</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">class_name</span><span class="p">,</span> <span class="n">base</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_get_mixins_</span><span class="p">(</span><span class="n">mcls</span><span class="p">,</span> <span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Returns the type for creating enum members, and the first inherited</span>
|
|
<span class="sd"> enum class.</span>
|
|
|
|
<span class="sd"> bases: the tuple of bases that was given to __new__</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="nb">object</span><span class="p">,</span> <span class="n">Enum</span>
|
|
<span class="c1"># ensure final parent class is an Enum derivative, find any concrete</span>
|
|
<span class="c1"># data type, and check that Enum has no members</span>
|
|
<span class="n">first_enum</span> <span class="o">=</span> <span class="n">bases</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">first_enum</span><span class="p">,</span> <span class="n">EnumType</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"new enumerations should be created as "</span>
|
|
<span class="s2">"`EnumName([mixin_type, ...] [data_type,] enum_type)`"</span><span class="p">)</span>
|
|
<span class="n">member_type</span> <span class="o">=</span> <span class="n">mcls</span><span class="o">.</span><span class="n">_find_data_type_</span><span class="p">(</span><span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">object</span>
|
|
<span class="k">return</span> <span class="n">member_type</span><span class="p">,</span> <span class="n">first_enum</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_find_data_repr_</span><span class="p">(</span><span class="n">mcls</span><span class="p">,</span> <span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span>
|
|
<span class="k">for</span> <span class="n">chain</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">chain</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="nb">object</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">EnumType</span><span class="p">):</span>
|
|
<span class="c1"># if we hit an Enum, use it's _value_repr_</span>
|
|
<span class="k">return</span> <span class="n">base</span><span class="o">.</span><span class="n">_value_repr_</span>
|
|
<span class="k">elif</span> <span class="s1">'__repr__'</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="c1"># this is our data repr</span>
|
|
<span class="c1"># double-check if a dataclass with a default __repr__</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="s1">'__dataclass_fields__'</span> <span class="ow">in</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="ow">and</span> <span class="s1">'__dataclass_params__'</span> <span class="ow">in</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="ow">and</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="s1">'__dataclass_params__'</span><span class="p">]</span><span class="o">.</span><span class="n">repr</span>
|
|
<span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">_dataclass_repr</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="s1">'__repr__'</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_find_data_type_</span><span class="p">(</span><span class="n">mcls</span><span class="p">,</span> <span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span>
|
|
<span class="c1"># a datatype has a __new__ method, or a __dataclass_fields__ attribute</span>
|
|
<span class="n">data_types</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="n">base_chain</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">chain</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
|
|
<span class="n">candidate</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">chain</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">:</span>
|
|
<span class="n">base_chain</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">base</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">base</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">EnumType</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">base</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">object</span><span class="p">:</span>
|
|
<span class="n">data_types</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">base</span><span class="o">.</span><span class="n">_member_type_</span><span class="p">)</span>
|
|
<span class="k">break</span>
|
|
<span class="k">elif</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="ow">or</span> <span class="s1">'__dataclass_fields__'</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">data_types</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">candidate</span> <span class="ow">or</span> <span class="n">base</span><span class="p">)</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">candidate</span> <span class="o">=</span> <span class="n">candidate</span> <span class="ow">or</span> <span class="n">base</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_types</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'too many data types for </span><span class="si">%r</span><span class="s1">: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">class_name</span><span class="p">,</span> <span class="n">data_types</span><span class="p">))</span>
|
|
<span class="k">elif</span> <span class="n">data_types</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">data_types</span><span class="o">.</span><span class="n">pop</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="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_find_new_</span><span class="p">(</span><span class="n">mcls</span><span class="p">,</span> <span class="n">classdict</span><span class="p">,</span> <span class="n">member_type</span><span class="p">,</span> <span class="n">first_enum</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Returns the __new__ to be used for creating the enum members.</span>
|
|
|
|
<span class="sd"> classdict: the class dictionary given to __new__</span>
|
|
<span class="sd"> member_type: the data type whose __new__ will be used by default</span>
|
|
<span class="sd"> first_enum: enumeration to check for an overriding __new__</span>
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># now find the correct __new__, checking to see of one was defined</span>
|
|
<span class="c1"># by the user; also check earlier enum classes in case a __new__ was</span>
|
|
<span class="c1"># saved as __new_member__</span>
|
|
<span class="fm">__new__</span> <span class="o">=</span> <span class="n">classdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__new__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
|
|
<span class="c1"># should __new__ be saved as __new_member__ later?</span>
|
|
<span class="n">save_new</span> <span class="o">=</span> <span class="n">first_enum</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
|
|
|
|
<span class="k">if</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># check all possibles for __new_member__ before falling back to</span>
|
|
<span class="c1"># __new__</span>
|
|
<span class="k">for</span> <span class="n">method</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'__new_member__'</span><span class="p">,</span> <span class="s1">'__new__'</span><span class="p">):</span>
|
|
<span class="k">for</span> <span class="n">possible</span> <span class="ow">in</span> <span class="p">(</span><span class="n">member_type</span><span class="p">,</span> <span class="n">first_enum</span><span class="p">):</span>
|
|
<span class="n">target</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">possible</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">target</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">{</span>
|
|
<span class="kc">None</span><span class="p">,</span>
|
|
<span class="kc">None</span><span class="o">.</span><span class="fm">__new__</span><span class="p">,</span>
|
|
<span class="nb">object</span><span class="o">.</span><span class="fm">__new__</span><span class="p">,</span>
|
|
<span class="n">Enum</span><span class="o">.</span><span class="fm">__new__</span><span class="p">,</span>
|
|
<span class="p">}:</span>
|
|
<span class="fm">__new__</span> <span class="o">=</span> <span class="n">target</span>
|
|
<span class="k">break</span>
|
|
<span class="k">if</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="fm">__new__</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__new__</span>
|
|
|
|
<span class="c1"># if a non-object.__new__ is used then whatever value/tuple was</span>
|
|
<span class="c1"># assigned to the enum member name will be passed to __new__ and to the</span>
|
|
<span class="c1"># new enum member's __init__</span>
|
|
<span class="k">if</span> <span class="n">first_enum</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="fm">__new__</span> <span class="ow">in</span> <span class="p">(</span><span class="n">Enum</span><span class="o">.</span><span class="fm">__new__</span><span class="p">,</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__new__</span><span class="p">):</span>
|
|
<span class="n">use_args</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">use_args</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">return</span> <span class="fm">__new__</span><span class="p">,</span> <span class="n">save_new</span><span class="p">,</span> <span class="n">use_args</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_add_member_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="p">):</span>
|
|
<span class="c1"># _value_ structures are not updated</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</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">member</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">NameError</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1"> is already bound: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">[</span><span class="n">name</span><span class="p">]))</span>
|
|
<span class="k">return</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># if necessary, get redirect in place and then add it to _member_map_</span>
|
|
<span class="n">found_descriptor</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">descriptor_type</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">class_type</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
|
|
<span class="n">attr</span> <span class="o">=</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">attr</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">attr</span><span class="p">,</span> <span class="p">(</span><span class="nb">property</span><span class="p">,</span> <span class="n">DynamicClassAttribute</span><span class="p">)):</span>
|
|
<span class="n">found_descriptor</span> <span class="o">=</span> <span class="n">attr</span>
|
|
<span class="n">class_type</span> <span class="o">=</span> <span class="n">base</span>
|
|
<span class="n">descriptor_type</span> <span class="o">=</span> <span class="s1">'enum'</span>
|
|
<span class="k">break</span>
|
|
<span class="k">elif</span> <span class="n">_is_descriptor</span><span class="p">(</span><span class="n">attr</span><span class="p">):</span>
|
|
<span class="n">found_descriptor</span> <span class="o">=</span> <span class="n">attr</span>
|
|
<span class="n">descriptor_type</span> <span class="o">=</span> <span class="n">descriptor_type</span> <span class="ow">or</span> <span class="s1">'desc'</span>
|
|
<span class="n">class_type</span> <span class="o">=</span> <span class="n">class_type</span> <span class="ow">or</span> <span class="n">base</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">descriptor_type</span> <span class="o">=</span> <span class="s1">'attr'</span>
|
|
<span class="n">class_type</span> <span class="o">=</span> <span class="n">base</span>
|
|
<span class="k">if</span> <span class="n">found_descriptor</span><span class="p">:</span>
|
|
<span class="n">redirect</span> <span class="o">=</span> <span class="nb">property</span><span class="p">()</span>
|
|
<span class="n">redirect</span><span class="o">.</span><span class="n">member</span> <span class="o">=</span> <span class="n">member</span>
|
|
<span class="n">redirect</span><span class="o">.</span><span class="n">__set_name__</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="n">descriptor_type</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'enum'</span><span class="p">,</span> <span class="s1">'desc'</span><span class="p">):</span>
|
|
<span class="c1"># earlier descriptor found; copy fget, fset, fdel to this one.</span>
|
|
<span class="n">redirect</span><span class="o">.</span><span class="n">fget</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">found_descriptor</span><span class="p">,</span> <span class="s1">'fget'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">redirect</span><span class="o">.</span><span class="n">_get</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">found_descriptor</span><span class="p">,</span> <span class="s1">'__get__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">redirect</span><span class="o">.</span><span class="n">fset</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">found_descriptor</span><span class="p">,</span> <span class="s1">'fset'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">redirect</span><span class="o">.</span><span class="n">_set</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">found_descriptor</span><span class="p">,</span> <span class="s1">'__set__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">redirect</span><span class="o">.</span><span class="n">fdel</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">found_descriptor</span><span class="p">,</span> <span class="s1">'fdel'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">redirect</span><span class="o">.</span><span class="n">_del</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">found_descriptor</span><span class="p">,</span> <span class="s1">'__delete__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">redirect</span><span class="o">.</span><span class="n">_attr_type</span> <span class="o">=</span> <span class="n">descriptor_type</span>
|
|
<span class="n">redirect</span><span class="o">.</span><span class="n">_cls_type</span> <span class="o">=</span> <span class="n">class_type</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">redirect</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="p">)</span>
|
|
<span class="c1"># now add to _member_map_ (even aliases)</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">member</span>
|
|
|
|
<span class="n">EnumMeta</span> <span class="o">=</span> <span class="n">EnumType</span> <span class="c1"># keep EnumMeta name for backwards compatibility</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">Enum</span><span class="p">(</span><span class="n">metaclass</span><span class="o">=</span><span class="n">EnumType</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Create a collection of name/value pairs.</span>
|
|
|
|
<span class="sd"> Example enumeration:</span>
|
|
|
|
<span class="sd"> >>> class Color(Enum):</span>
|
|
<span class="sd"> ... RED = 1</span>
|
|
<span class="sd"> ... BLUE = 2</span>
|
|
<span class="sd"> ... GREEN = 3</span>
|
|
|
|
<span class="sd"> Access them by:</span>
|
|
|
|
<span class="sd"> - attribute access:</span>
|
|
|
|
<span class="sd"> >>> Color.RED</span>
|
|
<span class="sd"> <Color.RED: 1></span>
|
|
|
|
<span class="sd"> - value lookup:</span>
|
|
|
|
<span class="sd"> >>> Color(1)</span>
|
|
<span class="sd"> <Color.RED: 1></span>
|
|
|
|
<span class="sd"> - name lookup:</span>
|
|
|
|
<span class="sd"> >>> Color['RED']</span>
|
|
<span class="sd"> <Color.RED: 1></span>
|
|
|
|
<span class="sd"> Enumerations can be iterated over, and know how many members they have:</span>
|
|
|
|
<span class="sd"> >>> len(Color)</span>
|
|
<span class="sd"> 3</span>
|
|
|
|
<span class="sd"> >>> list(Color)</span>
|
|
<span class="sd"> [<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]</span>
|
|
|
|
<span class="sd"> Methods can be added to enumerations, and members can have their own</span>
|
|
<span class="sd"> attributes -- see the documentation for details.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__signature__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="s1">'(*values)'</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="s1">'(new_class_name, /, names, *, module=None, qualname=None, type=None, start=1, boundary=None)'</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">value</span><span class="p">):</span>
|
|
<span class="c1"># all enum instances are actually created during class construction</span>
|
|
<span class="c1"># without calling this method; this method is called by the metaclass'</span>
|
|
<span class="c1"># __call__ (i.e. Color(3) ), and by pickle</span>
|
|
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="ow">is</span> <span class="bp">cls</span><span class="p">:</span>
|
|
<span class="c1"># For lookups like Color(Color.RED)</span>
|
|
<span class="k">return</span> <span class="n">value</span>
|
|
<span class="c1"># by-value search for a matching enum member</span>
|
|
<span class="c1"># see if it's in the reverse mapping (for hashable values)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">[</span><span class="n">value</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="c1"># Not found, no need to do long O(n) search</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="c1"># not there, now do long search -- O(n) behavior</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">unhashable_values</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_unhashable_values_map_</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">unhashable_values</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">cls</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="p">,</span> <span class="n">member</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="n">member</span><span class="o">.</span><span class="n">_value_</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">cls</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
|
|
<span class="c1"># still not found -- verify that members exist, in-case somebody got here mistakenly</span>
|
|
<span class="c1"># (such as via super when trying to override __new__)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="s1">'_</span><span class="si">%s</span><span class="s1">__in_progress'</span> <span class="o">%</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'do not use `super().__new__; call the appropriate __new__ directly'</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</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"> has no members defined"</span> <span class="o">%</span> <span class="bp">cls</span><span class="p">)</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># still not found -- try _missing_ hook</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">exc</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">result</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_missing_</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
|
<span class="n">exc</span> <span class="o">=</span> <span class="n">e</span>
|
|
<span class="n">result</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">result</span>
|
|
<span class="k">elif</span> <span class="p">(</span>
|
|
<span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">Flag</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="n">EJECT</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="nb">int</span><span class="p">)</span>
|
|
<span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">result</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">ve_exc</span> <span class="o">=</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2"> is not a valid </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__qualname__</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">result</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">exc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">ve_exc</span>
|
|
<span class="k">elif</span> <span class="n">exc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">exc</span> <span class="o">=</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s1">'error in </span><span class="si">%s</span><span class="s1">._missing_: returned </span><span class="si">%r</span><span class="s1"> instead of None or a valid member'</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">result</span><span class="p">)</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">exc</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">):</span>
|
|
<span class="n">exc</span><span class="o">.</span><span class="n">__context__</span> <span class="o">=</span> <span class="n">ve_exc</span>
|
|
<span class="k">raise</span> <span class="n">exc</span>
|
|
<span class="k">finally</span><span class="p">:</span>
|
|
<span class="c1"># ensure all variables that could hold an exception are destroyed</span>
|
|
<span class="n">exc</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">ve_exc</span> <span class="o">=</span> <span class="kc">None</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="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_add_alias_</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="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="n">_add_member_</span><span class="p">(</span><span class="n">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="nf">_add_value_alias_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">[</span><span class="n">value</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">self</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 already bound: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">[</span><span class="n">value</span><span class="p">]))</span>
|
|
<span class="k">return</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="c1"># unhashable value, do long search</span>
|
|
<span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">m</span><span class="o">.</span><span class="n">_value_</span> <span class="o">==</span> <span class="n">value</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">m</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">self</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 already bound: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">[</span><span class="n">value</span><span class="p">]))</span>
|
|
<span class="k">return</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># This may fail if value is not hashable. We can't add the value</span>
|
|
<span class="c1"># to the map, and by-value lookups for this value will be</span>
|
|
<span class="c1"># linear.</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_hashable_values_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="c1"># keep track of the value in a list so containment checks are quick</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_unhashable_values_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_unhashable_values_map_</span><span class="o">.</span><span class="n">setdefault</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="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
|
|
<span class="nd">@staticmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_generate_next_value_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">start</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">last_values</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Generate the next value when not given.</span>
|
|
|
|
<span class="sd"> name: the name of the member</span>
|
|
<span class="sd"> start: the initial start value or None</span>
|
|
<span class="sd"> count: the number of existing members</span>
|
|
<span class="sd"> last_values: the list of values assigned</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">last_values</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">start</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">last_value</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">last_values</span><span class="p">)</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'unable to sort non-numeric values'</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">last_value</span> <span class="o">+</span> <span class="mi">1</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'unable to increment </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">last_value</span><span class="p">,</span> <span class="p">))</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_missing_</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="k">return</span> <span class="kc">None</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">v_repr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="n">_value_repr_</span> <span class="ow">or</span> <span class="nb">repr</span>
|
|
<span class="k">return</span> <span class="s2">"<</span><span class="si">%s</span><span class="s2">.</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="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="o">.</span><span class="n">_name_</span><span class="p">,</span> <span class="n">v_repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="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="s2">"</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="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="o">.</span><span class="n">_name_</span><span class="p">,</span> <span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__dir__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Returns public methods and other interesting attributes.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">interesting</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">object</span><span class="p">:</span>
|
|
<span class="n">interesting</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="nb">object</span><span class="o">.</span><span class="fm">__dir__</span><span class="p">(</span><span class="bp">self</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="bp">self</span><span class="p">,</span> <span class="s1">'__dict__'</span><span class="p">,</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="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span>
|
|
<span class="n">interesting</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="bp">cls</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="n">mro</span><span class="p">():</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">obj</span> <span class="ow">in</span> <span class="bp">cls</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="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="p">:</span>
|
|
<span class="k">continue</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">property</span><span class="p">):</span>
|
|
<span class="c1"># that's an enum.property</span>
|
|
<span class="k">if</span> <span class="n">obj</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="ow">or</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span>
|
|
<span class="n">interesting</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">else</span><span class="p">:</span>
|
|
<span class="c1"># in case it was added by `dir(self)`</span>
|
|
<span class="n">interesting</span><span class="o">.</span><span class="n">discard</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span>
|
|
<span class="n">interesting</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="n">names</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span>
|
|
<span class="nb">set</span><span class="p">([</span><span class="s1">'__class__'</span><span class="p">,</span> <span class="s1">'__doc__'</span><span class="p">,</span> <span class="s1">'__eq__'</span><span class="p">,</span> <span class="s1">'__hash__'</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">])</span>
|
|
<span class="o">|</span> <span class="n">interesting</span>
|
|
<span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">names</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__format__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">format_spec</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">str</span><span class="o">.</span><span class="fm">__format__</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="n">format_spec</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="k">def</span><span class="w"> </span><span class="nf">__reduce_ex__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proto</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">,</span> <span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__deepcopy__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">memo</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__copy__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span>
|
|
|
|
<span class="c1"># enum.property is used to provide access to the `name` and</span>
|
|
<span class="c1"># `value` attributes of enum members while keeping some measure of</span>
|
|
<span class="c1"># protection from modification, while still allowing for an enumeration</span>
|
|
<span class="c1"># to have members named `name` and `value`. This works because each</span>
|
|
<span class="c1"># instance of enum.property saves its companion member, which it returns</span>
|
|
<span class="c1"># on class lookup; on instance lookup it either executes a provided function</span>
|
|
<span class="c1"># or raises an AttributeError.</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="w"> </span><span class="sd">"""The name of the Enum member."""</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">value</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""The value of the Enum member."""</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">ReprEnum</span><span class="p">(</span><span class="n">Enum</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Only changes the repr(), leaving str() and format() to the mixed-in type.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">IntEnum</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">ReprEnum</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Enum where members are also (and must be) ints</span>
|
|
<span class="sd"> """</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">StrEnum</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">ReprEnum</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Enum where members are also (and must be) strings</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="o">*</span><span class="n">values</span><span class="p">):</span>
|
|
<span class="s2">"values must already be of type `str`"</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o">></span> <span class="mi">3</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'too many arguments for str(): </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">values</span><span class="p">,</span> <span class="p">))</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="c1"># it must be a string</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1"> is not a string'</span> <span class="o">%</span> <span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">))</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">2</span><span class="p">:</span>
|
|
<span class="c1"># check that encoding argument is a string</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'encoding must be a string, not </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">))</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
|
|
<span class="c1"># check that errors argument is a string</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'errors must be a string, not </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="o">*</span><span class="n">values</span><span class="p">)</span>
|
|
<span class="n">member</span> <span class="o">=</span> <span class="nb">str</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="k">return</span> <span class="n">member</span>
|
|
|
|
<span class="nd">@staticmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_generate_next_value_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">start</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">last_values</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Return the lower-cased version of the member name.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">pickle_by_global_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proto</span><span class="p">):</span>
|
|
<span class="c1"># should not be used with Flag-type enums</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
|
|
<span class="n">_reduce_ex_by_global_name</span> <span class="o">=</span> <span class="n">pickle_by_global_name</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">pickle_by_enum_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proto</span><span class="p">):</span>
|
|
<span class="c1"># should not be used with Flag-type enums</span>
|
|
<span class="k">return</span> <span class="nb">getattr</span><span class="p">,</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="p">)</span>
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">FlagBoundary</span><span class="p">(</span><span class="n">StrEnum</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> control how out of range values are handled</span>
|
|
<span class="sd"> "strict" -> error is raised [default for Flag]</span>
|
|
<span class="sd"> "conform" -> extra bits are discarded</span>
|
|
<span class="sd"> "eject" -> lose flag status</span>
|
|
<span class="sd"> "keep" -> keep flag status and all bits [default for IntFlag]</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">STRICT</span> <span class="o">=</span> <span class="n">auto</span><span class="p">()</span>
|
|
<span class="n">CONFORM</span> <span class="o">=</span> <span class="n">auto</span><span class="p">()</span>
|
|
<span class="n">EJECT</span> <span class="o">=</span> <span class="n">auto</span><span class="p">()</span>
|
|
<span class="n">KEEP</span> <span class="o">=</span> <span class="n">auto</span><span class="p">()</span>
|
|
<span class="n">STRICT</span><span class="p">,</span> <span class="n">CONFORM</span><span class="p">,</span> <span class="n">EJECT</span><span class="p">,</span> <span class="n">KEEP</span> <span class="o">=</span> <span class="n">FlagBoundary</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">Flag</span><span class="p">(</span><span class="n">Enum</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="n">STRICT</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Support for flags</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">_numeric_repr_</span> <span class="o">=</span> <span class="nb">repr</span>
|
|
|
|
<span class="nd">@staticmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_generate_next_value_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">start</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">last_values</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Generate the next value when not given.</span>
|
|
|
|
<span class="sd"> name: the name of the member</span>
|
|
<span class="sd"> start: the initial start value or None</span>
|
|
<span class="sd"> count: the number of existing members</span>
|
|
<span class="sd"> last_values: the last value assigned or None</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">count</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">start</span> <span class="k">if</span> <span class="n">start</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="mi">1</span>
|
|
<span class="n">last_value</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">last_values</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">high_bit</span> <span class="o">=</span> <span class="n">_high_bit</span><span class="p">(</span><span class="n">last_value</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'invalid flag value </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="n">last_value</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
|
|
<span class="k">return</span> <span class="mi">2</span> <span class="o">**</span> <span class="p">(</span><span class="n">high_bit</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_iter_member_by_value_</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="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Extract all members from the value in definition (i.e. increasing value) order.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">_iter_bits_lsb</span><span class="p">(</span><span class="n">value</span> <span class="o">&</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_flag_mask_</span><span class="p">):</span>
|
|
<span class="k">yield</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">val</span><span class="p">)</span>
|
|
|
|
<span class="n">_iter_member_</span> <span class="o">=</span> <span class="n">_iter_member_by_value_</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_iter_member_by_def_</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="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Extract all members from the value in definition order.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">yield from</span> <span class="nb">sorted</span><span class="p">(</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_iter_member_by_value_</span><span class="p">(</span><span class="n">value</span><span class="p">),</span>
|
|
<span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="n">m</span><span class="o">.</span><span class="n">_sort_order_</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_missing_</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="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Create a composite member containing all canonical members present in `value`.</span>
|
|
|
|
<span class="sd"> If non-member values are present, result depends on `_boundary_` setting.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">int</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"> is not a valid </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__qualname__</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="c1"># check boundaries</span>
|
|
<span class="c1"># - value must be in range (e.g. -16 <-> +15, i.e. ~15 <-> 15)</span>
|
|
<span class="c1"># - value must not include any skipped flags (e.g. if bit 2 is not</span>
|
|
<span class="c1"># defined, then 0d10 is invalid)</span>
|
|
<span class="n">flag_mask</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_flag_mask_</span>
|
|
<span class="n">singles_mask</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_singles_mask_</span>
|
|
<span class="n">all_bits</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_all_bits_</span>
|
|
<span class="n">neg_value</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="ow">not</span> <span class="o">~</span><span class="n">all_bits</span> <span class="o"><=</span> <span class="n">value</span> <span class="o"><=</span> <span class="n">all_bits</span>
|
|
<span class="ow">or</span> <span class="n">value</span> <span class="o">&</span> <span class="p">(</span><span class="n">all_bits</span> <span class="o">^</span> <span class="n">flag_mask</span><span class="p">)</span>
|
|
<span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="n">STRICT</span><span class="p">:</span>
|
|
<span class="n">max_bits</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">bit_length</span><span class="p">(),</span> <span class="n">flag_mask</span><span class="o">.</span><span class="n">bit_length</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"> invalid value </span><span class="si">%r</span><span class="se">\n</span><span class="s2"> given </span><span class="si">%s</span><span class="se">\n</span><span class="s2"> allowed </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</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="nb">bin</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">max_bits</span><span class="p">),</span> <span class="nb">bin</span><span class="p">(</span><span class="n">flag_mask</span><span class="p">,</span> <span class="n">max_bits</span><span class="p">),</span>
|
|
<span class="p">))</span>
|
|
<span class="k">elif</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="n">CONFORM</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">value</span> <span class="o">&</span> <span class="n">flag_mask</span>
|
|
<span class="k">elif</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="n">EJECT</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">value</span>
|
|
<span class="k">elif</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="n">KEEP</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="nb">max</span><span class="p">(</span><span class="n">all_bits</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="o">**</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">bit_length</span><span class="p">()))</span>
|
|
<span class="o">+</span> <span class="n">value</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">'</span><span class="si">%r</span><span class="s1"> unknown flag boundary </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span><span class="p">,</span> <span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="n">neg_value</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">all_bits</span> <span class="o">+</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">value</span>
|
|
<span class="c1"># get members and unknown</span>
|
|
<span class="n">unknown</span> <span class="o">=</span> <span class="n">value</span> <span class="o">&</span> <span class="o">~</span><span class="n">flag_mask</span>
|
|
<span class="n">aliases</span> <span class="o">=</span> <span class="n">value</span> <span class="o">&</span> <span class="o">~</span><span class="n">singles_mask</span>
|
|
<span class="n">member_value</span> <span class="o">=</span> <span class="n">value</span> <span class="o">&</span> <span class="n">singles_mask</span>
|
|
<span class="k">if</span> <span class="n">unknown</span> <span class="ow">and</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">KEEP</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">%s</span><span class="s1">(</span><span class="si">%r</span><span class="s1">) --> unknown values </span><span class="si">%r</span><span class="s1"> [</span><span class="si">%s</span><span class="s1">]'</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">unknown</span><span class="p">,</span> <span class="nb">bin</span><span class="p">(</span><span class="n">unknown</span><span class="p">))</span>
|
|
<span class="p">)</span>
|
|
<span class="c1"># normal Flag?</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span>
|
|
<span class="c1"># construct a singleton enum pseudo-member</span>
|
|
<span class="n">pseudo_member</span> <span class="o">=</span> <span class="nb">object</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="k">else</span><span class="p">:</span>
|
|
<span class="n">pseudo_member</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_type_</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="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">pseudo_member</span><span class="p">,</span> <span class="s1">'_value_'</span><span class="p">):</span>
|
|
<span class="n">pseudo_member</span><span class="o">.</span><span class="n">_value_</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="k">if</span> <span class="n">member_value</span> <span class="ow">or</span> <span class="n">aliases</span><span class="p">:</span>
|
|
<span class="n">members</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">combined_value</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_iter_member_</span><span class="p">(</span><span class="n">member_value</span><span class="p">):</span>
|
|
<span class="n">members</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
|
|
<span class="n">combined_value</span> <span class="o">|=</span> <span class="n">m</span><span class="o">.</span><span class="n">_value_</span>
|
|
<span class="k">if</span> <span class="n">aliases</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">member_value</span> <span class="o">|</span> <span class="n">aliases</span>
|
|
<span class="k">for</span> <span class="n">n</span><span class="p">,</span> <span class="n">pm</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">pm</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">members</span> <span class="ow">and</span> <span class="n">pm</span><span class="o">.</span><span class="n">_value_</span> <span class="ow">and</span> <span class="n">pm</span><span class="o">.</span><span class="n">_value_</span> <span class="o">&</span> <span class="n">value</span> <span class="o">==</span> <span class="n">pm</span><span class="o">.</span><span class="n">_value_</span><span class="p">:</span>
|
|
<span class="n">members</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pm</span><span class="p">)</span>
|
|
<span class="n">combined_value</span> <span class="o">|=</span> <span class="n">pm</span><span class="o">.</span><span class="n">_value_</span>
|
|
<span class="n">unknown</span> <span class="o">=</span> <span class="n">value</span> <span class="o">^</span> <span class="n">combined_value</span>
|
|
<span class="n">pseudo_member</span><span class="o">.</span><span class="n">_name_</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">m</span><span class="o">.</span><span class="n">_name_</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">members</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">combined_value</span><span class="p">:</span>
|
|
<span class="n">pseudo_member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">elif</span> <span class="n">unknown</span> <span class="ow">and</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="n">STRICT</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">: no members with value </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">unknown</span><span class="p">))</span>
|
|
<span class="k">elif</span> <span class="n">unknown</span><span class="p">:</span>
|
|
<span class="n">pseudo_member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">+=</span> <span class="s1">'|</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_numeric_repr_</span><span class="p">(</span><span class="n">unknown</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">pseudo_member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="c1"># use setdefault in case another thread already created a composite</span>
|
|
<span class="c1"># with this value</span>
|
|
<span class="c1"># note: zero is a special case -- always add it</span>
|
|
<span class="n">pseudo_member</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">pseudo_member</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">neg_value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">[</span><span class="n">neg_value</span><span class="p">]</span> <span class="o">=</span> <span class="n">pseudo_member</span>
|
|
<span class="k">return</span> <span class="n">pseudo_member</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__contains__</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="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Returns True if self has at least the same flags set as other.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="s2">"unsupported operand type(s) for 'in': </span><span class="si">%r</span><span class="s2"> and </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span>
|
|
<span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="vm">__qualname__</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">__qualname__</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">other</span><span class="o">.</span><span class="n">_value_</span> <span class="o">&</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_value_</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Returns flags in definition order.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">yield from</span> <span class="bp">self</span><span class="o">.</span><span class="n">_iter_member_</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__len__</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">_value_</span><span class="o">.</span><span class="n">bit_count</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">cls_name</span> <span class="o">=</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="n">v_repr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="n">_value_repr_</span> <span class="ow">or</span> <span class="nb">repr</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="s2">"<</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">cls_name</span><span class="p">,</span> <span class="n">v_repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">))</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="s2">"<</span><span class="si">%s</span><span class="s2">.</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">cls_name</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="n">v_repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">cls_name</span> <span class="o">=</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="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="s1">'</span><span class="si">%s</span><span class="s1">(</span><span class="si">%r</span><span class="s1">)'</span> <span class="o">%</span> <span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="s2">"</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">cls_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__bool__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_get_value</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">flag</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">flag</span><span class="o">.</span><span class="n">_value_</span>
|
|
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">object</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_member_type_</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">flag</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__or__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="n">other_value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">other_value</span> <span class="ow">is</span> <span class="bp">NotImplemented</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="k">for</span> <span class="n">flag</span> <span class="ow">in</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="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="n">flag</span><span class="si">}</span><span class="s2">' cannot be combined with other flags with |"</span><span class="p">)</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="n">value</span> <span class="o">|</span> <span class="n">other_value</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__and__</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="n">other_value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">other_value</span> <span class="ow">is</span> <span class="bp">NotImplemented</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="k">for</span> <span class="n">flag</span> <span class="ow">in</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="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="n">flag</span><span class="si">}</span><span class="s2">' cannot be combined with other flags with &"</span><span class="p">)</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="n">value</span> <span class="o">&</span> <span class="n">other_value</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__xor__</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="n">other_value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">other_value</span> <span class="ow">is</span> <span class="bp">NotImplemented</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="k">for</span> <span class="n">flag</span> <span class="ow">in</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="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="n">flag</span><span class="si">}</span><span class="s2">' cannot be combined with other flags with ^"</span><span class="p">)</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="n">value</span> <span class="o">^</span> <span class="n">other_value</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__invert__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2">' cannot be inverted"</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_inverted_</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">in</span> <span class="p">(</span><span class="n">EJECT</span><span class="p">,</span> <span class="n">KEEP</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_inverted_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="o">~</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_inverted_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_singles_mask_</span> <span class="o">&</span> <span class="o">~</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_inverted_</span>
|
|
|
|
<span class="fm">__rand__</span> <span class="o">=</span> <span class="fm">__and__</span>
|
|
<span class="fm">__ror__</span> <span class="o">=</span> <span class="fm">__or__</span>
|
|
<span class="fm">__rxor__</span> <span class="o">=</span> <span class="fm">__xor__</span>
|
|
|
|
|
|
<div class="viewcode-block" id="IntFlag">
|
|
<a class="viewcode-back" href="../api/evennia.utils.dbserialize.html#evennia.utils.dbserialize.IntFlag">[docs]</a>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">IntFlag</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">ReprEnum</span><span class="p">,</span> <span class="n">Flag</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="n">KEEP</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Support for integer-based Flags</span>
|
|
<span class="sd"> """</span></div>
|
|
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_high_bit</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> returns index of highest bit, or -1 if value is zero or negative</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">value</span><span class="o">.</span><span class="n">bit_length</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">unique</span><span class="p">(</span><span class="n">enumeration</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Class decorator for enumerations ensuring unique member values.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">duplicates</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">member</span> <span class="ow">in</span> <span class="n">enumeration</span><span class="o">.</span><span class="n">__members__</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="o">!=</span> <span class="n">member</span><span class="o">.</span><span class="n">name</span><span class="p">:</span>
|
|
<span class="n">duplicates</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">member</span><span class="o">.</span><span class="n">name</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">duplicates</span><span class="p">:</span>
|
|
<span class="n">alias_details</span> <span class="o">=</span> <span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
|
|
<span class="p">[</span><span class="s2">"</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">alias</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="k">for</span> <span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="ow">in</span> <span class="n">duplicates</span><span class="p">])</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'duplicate values found in </span><span class="si">%r</span><span class="s1">: </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span>
|
|
<span class="p">(</span><span class="n">enumeration</span><span class="p">,</span> <span class="n">alias_details</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">enumeration</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_dataclass_repr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">dcf</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__dataclass_fields__</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="s1">'</span><span class="si">%s</span><span class="s1">=</span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">k</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">k</span><span class="p">))</span>
|
|
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">dcf</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="n">dcf</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="o">.</span><span class="n">repr</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">global_enum_repr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> use module.enum_name instead of class.enum_name</span>
|
|
|
|
<span class="sd"> the module is the last module in case of a multi-module name</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">module</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__module__</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="k">return</span> <span class="s1">'</span><span class="si">%s</span><span class="s1">.</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">global_flag_repr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> use module.flag_name instead of class.flag_name</span>
|
|
|
|
<span class="sd"> the module is the last module in case of a multi-module name</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">module</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__module__</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="n">cls_name</span> <span class="o">=</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="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="s2">"</span><span class="si">%s</span><span class="s2">.</span><span class="si">%s</span><span class="s2">(</span><span class="si">%r</span><span class="s2">)"</span> <span class="o">%</span> <span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">cls_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">_is_single_bit</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="s1">'</span><span class="si">%s</span><span class="s1">.</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">FlagBoundary</span><span class="o">.</span><span class="n">KEEP</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="s1">'</span><span class="si">%s</span><span class="s1">.</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">module</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="bp">self</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'|'</span><span class="p">)])</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'|'</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">n</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span>
|
|
<span class="n">name</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">name</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'</span><span class="si">%s</span><span class="s1">.</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">n</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">name</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">global_str</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> use enum_name instead of class.enum_name</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">cls_name</span> <span class="o">=</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="k">return</span> <span class="s2">"</span><span class="si">%s</span><span class="s2">(</span><span class="si">%r</span><span class="s2">)"</span> <span class="o">%</span> <span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">global_enum</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">update_str</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> decorator that makes the repr() of an enum member reference its module</span>
|
|
<span class="sd"> instead of its class; also exports all members to the enum's module's</span>
|
|
<span class="sd"> global namespace</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="fm">__repr__</span> <span class="o">=</span> <span class="n">global_flag_repr</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="fm">__repr__</span> <span class="o">=</span> <span class="n">global_enum_repr</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">ReprEnum</span><span class="p">)</span> <span class="ow">or</span> <span class="n">update_str</span><span class="p">:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="fm">__str__</span> <span class="o">=</span> <span class="n">global_str</span>
|
|
<span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__module__</span><span class="p">]</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">update</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="k">return</span> <span class="bp">cls</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_simple_enum</span><span class="p">(</span><span class="n">etype</span><span class="o">=</span><span class="n">Enum</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">use_args</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Class decorator that converts a normal class into an :class:`Enum`. No</span>
|
|
<span class="sd"> safety checks are done, and some advanced behavior (such as</span>
|
|
<span class="sd"> :func:`__init_subclass__`) is not available. Enum creation can be faster</span>
|
|
<span class="sd"> using :func:`_simple_enum`.</span>
|
|
|
|
<span class="sd"> >>> from enum import Enum, _simple_enum</span>
|
|
<span class="sd"> >>> @_simple_enum(Enum)</span>
|
|
<span class="sd"> ... class Color:</span>
|
|
<span class="sd"> ... RED = auto()</span>
|
|
<span class="sd"> ... GREEN = auto()</span>
|
|
<span class="sd"> ... BLUE = auto()</span>
|
|
<span class="sd"> >>> Color</span>
|
|
<span class="sd"> <enum 'Color'></span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">convert_class</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">nonlocal</span> <span class="n">use_args</span>
|
|
<span class="n">cls_name</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="k">if</span> <span class="n">use_args</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">use_args</span> <span class="o">=</span> <span class="n">etype</span><span class="o">.</span><span class="n">_use_args_</span>
|
|
<span class="fm">__new__</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__new__'</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">new_member</span> <span class="o">=</span> <span class="fm">__new__</span><span class="o">.</span><span class="vm">__func__</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">new_member</span> <span class="o">=</span> <span class="n">etype</span><span class="o">.</span><span class="n">_member_type_</span><span class="o">.</span><span class="fm">__new__</span>
|
|
<span class="n">attrs</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">body</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">if</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'__new_member__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_member</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_new_member_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_member</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_use_args_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">use_args</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_generate_next_value_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">gnv</span> <span class="o">=</span> <span class="n">etype</span><span class="o">.</span><span class="n">_generate_next_value_</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_member_names_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">member_names</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_member_map_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">member_map</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_value2member_map_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">value2member_map</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_hashable_values_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">hashable_values</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_unhashable_values_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">unhashable_values</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_unhashable_values_map_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_member_type_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">member_type</span> <span class="o">=</span> <span class="n">etype</span><span class="o">.</span><span class="n">_member_type_</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_value_repr_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">etype</span><span class="o">.</span><span class="n">_value_repr_</span>
|
|
<span class="k">if</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">etype</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_boundary_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">boundary</span> <span class="ow">or</span> <span class="n">etype</span><span class="o">.</span><span class="n">_boundary_</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_flag_mask_'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_all_bits_'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_singles_mask_'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'_inverted_'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'__or__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__or__</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'__xor__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__xor__</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'__and__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__and__</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'__ror__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__ror__</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'__rxor__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__rxor__</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'__rand__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__rand__</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'__invert__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__invert__</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">obj</span> <span class="ow">in</span> <span class="bp">cls</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="n">name</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'__dict__'</span><span class="p">,</span> <span class="s1">'__weakref__'</span><span class="p">):</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">if</span> <span class="n">_is_dunder</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_is_private</span><span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_is_sunder</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_is_descriptor</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">obj</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">attrs</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">obj</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__doc__'</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">body</span><span class="p">[</span><span class="s1">'__doc__'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'An enumeration.'</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># double check that repr and friends are not the mixin's or various</span>
|
|
<span class="c1"># things break (such as pickle)</span>
|
|
<span class="c1"># however, if the method is defined in the Enum itself, don't replace</span>
|
|
<span class="c1"># it</span>
|
|
<span class="n">enum_class</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="p">(</span><span class="n">etype</span><span class="p">,</span> <span class="p">),</span> <span class="n">body</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="n">boundary</span><span class="p">,</span> <span class="n">_simple</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'__repr__'</span><span class="p">,</span> <span class="s1">'__str__'</span><span class="p">,</span> <span class="s1">'__format__'</span><span class="p">,</span> <span class="s1">'__reduce_ex__'</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">body</span><span class="p">:</span>
|
|
<span class="c1"># check for mixin overrides before replacing</span>
|
|
<span class="n">enum_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">etype</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="n">found_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="n">object_method</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="n">data_type_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">member_type</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">found_method</span> <span class="ow">in</span> <span class="p">(</span><span class="n">data_type_method</span><span class="p">,</span> <span class="n">object_method</span><span class="p">):</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">enum_method</span><span class="p">)</span>
|
|
<span class="n">gnv_last_values</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span>
|
|
<span class="c1"># Flag / IntFlag</span>
|
|
<span class="n">single_bits</span> <span class="o">=</span> <span class="n">multi_bits</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">attrs</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">value</span><span class="p">,</span> <span class="n">auto</span><span class="p">)</span> <span class="ow">and</span> <span class="n">auto</span><span class="o">.</span><span class="n">value</span> <span class="ow">is</span> <span class="n">_auto_null</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">gnv</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="nb">len</span><span class="p">(</span><span class="n">member_names</span><span class="p">),</span> <span class="n">gnv_last_values</span><span class="p">)</span>
|
|
<span class="c1"># create basic member (possibly isolate value for alias check)</span>
|
|
<span class="k">if</span> <span class="n">use_args</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">)</span>
|
|
<span class="n">member</span> <span class="o">=</span> <span class="n">new_member</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="o">*</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">member</span> <span class="o">=</span> <span class="n">new_member</span><span class="p">(</span><span class="n">enum_class</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="kc">None</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="c1"># now check if alias</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">contained</span> <span class="o">=</span> <span class="n">value2member_map</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">member</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="n">contained</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="n">member</span><span class="o">.</span><span class="n">_value_</span> <span class="ow">in</span> <span class="n">unhashable_values</span> <span class="ow">or</span> <span class="n">member</span><span class="o">.</span><span class="n">value</span> <span class="ow">in</span> <span class="n">hashable_values</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">m</span><span class="o">.</span><span class="n">_value_</span> <span class="o">==</span> <span class="n">member</span><span class="o">.</span><span class="n">_value_</span><span class="p">:</span>
|
|
<span class="n">contained</span> <span class="o">=</span> <span class="n">m</span>
|
|
<span class="k">break</span>
|
|
<span class="k">if</span> <span class="n">contained</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># an alias to an existing member</span>
|
|
<span class="n">contained</span><span class="o">.</span><span class="n">_add_alias_</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="c1"># finish creating member</span>
|
|
<span class="n">member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">=</span> <span class="n">name</span>
|
|
<span class="n">member</span><span class="o">.</span><span class="vm">__objclass__</span> <span class="o">=</span> <span class="n">enum_class</span>
|
|
<span class="n">member</span><span class="o">.</span><span class="fm">__init__</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">_sort_order_</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">member_names</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'name'</span><span class="p">,</span> <span class="s1">'value'</span><span class="p">):</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="p">)</span>
|
|
<span class="n">member_map</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">member</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_add_member_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="p">)</span>
|
|
<span class="n">value2member_map</span><span class="p">[</span><span class="n">value</span><span class="p">]</span> <span class="o">=</span> <span class="n">member</span>
|
|
<span class="n">hashable_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">_is_single_bit</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="c1"># not a multi-bit alias, record in _member_names_ and _flag_mask_</span>
|
|
<span class="n">member_names</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">single_bits</span> <span class="o">|=</span> <span class="n">value</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">multi_bits</span> <span class="o">|=</span> <span class="n">value</span>
|
|
<span class="n">gnv_last_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_flag_mask_</span> <span class="o">=</span> <span class="n">single_bits</span> <span class="o">|</span> <span class="n">multi_bits</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_singles_mask_</span> <span class="o">=</span> <span class="n">single_bits</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_all_bits_</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">**</span> <span class="p">((</span><span class="n">single_bits</span><span class="o">|</span><span class="n">multi_bits</span><span class="p">)</span><span class="o">.</span><span class="n">bit_length</span><span class="p">())</span> <span class="o">-</span> <span class="mi">1</span>
|
|
<span class="c1"># set correct __iter__</span>
|
|
<span class="n">member_list</span> <span class="o">=</span> <span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">_value_</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">member_list</span> <span class="o">!=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">member_list</span><span class="p">):</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_iter_member_</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_iter_member_by_def_</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># Enum / IntEnum / StrEnum</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">attrs</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">value</span><span class="p">,</span> <span class="n">auto</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">value</span> <span class="ow">is</span> <span class="n">_auto_null</span><span class="p">:</span>
|
|
<span class="n">value</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">gnv</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="nb">len</span><span class="p">(</span><span class="n">member_names</span><span class="p">),</span> <span class="n">gnv_last_values</span><span class="p">)</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="c1"># create basic member (possibly isolate value for alias check)</span>
|
|
<span class="k">if</span> <span class="n">use_args</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">)</span>
|
|
<span class="n">member</span> <span class="o">=</span> <span class="n">new_member</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="o">*</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">member</span> <span class="o">=</span> <span class="n">new_member</span><span class="p">(</span><span class="n">enum_class</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="kc">None</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="c1"># now check if alias</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">contained</span> <span class="o">=</span> <span class="n">value2member_map</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">member</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="n">contained</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="n">member</span><span class="o">.</span><span class="n">_value_</span> <span class="ow">in</span> <span class="n">unhashable_values</span> <span class="ow">or</span> <span class="n">member</span><span class="o">.</span><span class="n">_value_</span> <span class="ow">in</span> <span class="n">hashable_values</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">m</span><span class="o">.</span><span class="n">_value_</span> <span class="o">==</span> <span class="n">member</span><span class="o">.</span><span class="n">_value_</span><span class="p">:</span>
|
|
<span class="n">contained</span> <span class="o">=</span> <span class="n">m</span>
|
|
<span class="k">break</span>
|
|
<span class="k">if</span> <span class="n">contained</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># an alias to an existing member</span>
|
|
<span class="n">contained</span><span class="o">.</span><span class="n">_add_alias_</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="c1"># finish creating member</span>
|
|
<span class="n">member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">=</span> <span class="n">name</span>
|
|
<span class="n">member</span><span class="o">.</span><span class="vm">__objclass__</span> <span class="o">=</span> <span class="n">enum_class</span>
|
|
<span class="n">member</span><span class="o">.</span><span class="fm">__init__</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">_sort_order_</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">member_names</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'name'</span><span class="p">,</span> <span class="s1">'value'</span><span class="p">):</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="p">)</span>
|
|
<span class="n">member_map</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">member</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_add_member_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="p">)</span>
|
|
<span class="n">member_names</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">gnv_last_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># This may fail if value is not hashable. We can't add the value</span>
|
|
<span class="c1"># to the map, and by-value lookups for this value will be</span>
|
|
<span class="c1"># linear.</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">member</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">hashable_values</span><span class="p">:</span>
|
|
<span class="n">hashable_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="c1"># keep track of the value in a list so containment checks are quick</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_unhashable_values_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">_unhashable_values_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="s1">'__new__'</span> <span class="ow">in</span> <span class="n">body</span><span class="p">:</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="n">__new_member__</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="fm">__new__</span>
|
|
<span class="n">enum_class</span><span class="o">.</span><span class="fm">__new__</span> <span class="o">=</span> <span class="n">Enum</span><span class="o">.</span><span class="fm">__new__</span>
|
|
<span class="k">return</span> <span class="n">enum_class</span>
|
|
<span class="k">return</span> <span class="n">convert_class</span>
|
|
|
|
<span class="nd">@_simple_enum</span><span class="p">(</span><span class="n">StrEnum</span><span class="p">)</span>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">EnumCheck</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> various conditions to check an enumeration for</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">CONTINUOUS</span> <span class="o">=</span> <span class="s2">"no skipped integer values"</span>
|
|
<span class="n">NAMED_FLAGS</span> <span class="o">=</span> <span class="s2">"multi-flag aliases may not contain unnamed flags"</span>
|
|
<span class="n">UNIQUE</span> <span class="o">=</span> <span class="s2">"one name per value"</span>
|
|
<span class="n">CONTINUOUS</span><span class="p">,</span> <span class="n">NAMED_FLAGS</span><span class="p">,</span> <span class="n">UNIQUE</span> <span class="o">=</span> <span class="n">EnumCheck</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">verify</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Check an enumeration for various constraints. (see EnumCheck)</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">checks</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">checks</span> <span class="o">=</span> <span class="n">checks</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">enumeration</span><span class="p">):</span>
|
|
<span class="n">checks</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">checks</span>
|
|
<span class="n">cls_name</span> <span class="o">=</span> <span class="n">enumeration</span><span class="o">.</span><span class="vm">__name__</span>
|
|
<span class="k">if</span> <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enumeration</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span>
|
|
<span class="n">enum_type</span> <span class="o">=</span> <span class="s1">'flag'</span>
|
|
<span class="k">elif</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enumeration</span><span class="p">,</span> <span class="n">Enum</span><span class="p">):</span>
|
|
<span class="n">enum_type</span> <span class="o">=</span> <span class="s1">'enum'</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="s2">"the 'verify' decorator only works with Enum and Flag"</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">check</span> <span class="ow">in</span> <span class="n">checks</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">check</span> <span class="ow">is</span> <span class="n">UNIQUE</span><span class="p">:</span>
|
|
<span class="c1"># check for duplicate names</span>
|
|
<span class="n">duplicates</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">member</span> <span class="ow">in</span> <span class="n">enumeration</span><span class="o">.</span><span class="n">__members__</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="o">!=</span> <span class="n">member</span><span class="o">.</span><span class="n">name</span><span class="p">:</span>
|
|
<span class="n">duplicates</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">member</span><span class="o">.</span><span class="n">name</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">duplicates</span><span class="p">:</span>
|
|
<span class="n">alias_details</span> <span class="o">=</span> <span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
|
|
<span class="p">[</span><span class="s2">"</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">alias</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="k">for</span> <span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="ow">in</span> <span class="n">duplicates</span><span class="p">])</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'aliases found in </span><span class="si">%r</span><span class="s1">: </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span>
|
|
<span class="p">(</span><span class="n">enumeration</span><span class="p">,</span> <span class="n">alias_details</span><span class="p">))</span>
|
|
<span class="k">elif</span> <span class="n">check</span> <span class="ow">is</span> <span class="n">CONTINUOUS</span><span class="p">:</span>
|
|
<span class="n">values</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">value</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">enumeration</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o"><</span> <span class="mi">2</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">low</span><span class="p">,</span> <span class="n">high</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">values</span><span class="p">),</span> <span class="nb">max</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
|
|
<span class="n">missing</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">enum_type</span> <span class="o">==</span> <span class="s1">'flag'</span><span class="p">:</span>
|
|
<span class="c1"># check for powers of two</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">_high_bit</span><span class="p">(</span><span class="n">low</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">_high_bit</span><span class="p">(</span><span class="n">high</span><span class="p">)):</span>
|
|
<span class="k">if</span> <span class="mi">2</span><span class="o">**</span><span class="n">i</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="n">append</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="n">i</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">enum_type</span> <span class="o">==</span> <span class="s1">'enum'</span><span class="p">:</span>
|
|
<span class="c1"># check for missing consecutive integers</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">low</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">high</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">i</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="n">append</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">'verify: unknown type </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="n">enum_type</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">missing</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">((</span><span class="s1">'invalid </span><span class="si">%s</span><span class="s1"> </span><span class="si">%r</span><span class="s1">: missing values </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span>
|
|
<span class="n">enum_type</span><span class="p">,</span> <span class="n">cls_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="nb">str</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">missing</span><span class="p">)))</span>
|
|
<span class="p">)[:</span><span class="mi">256</span><span class="p">])</span>
|
|
<span class="c1"># limit max length to protect against DOS attacks</span>
|
|
<span class="k">elif</span> <span class="n">check</span> <span class="ow">is</span> <span class="n">NAMED_FLAGS</span><span class="p">:</span>
|
|
<span class="c1"># examine each alias and check for unnamed flags</span>
|
|
<span class="n">member_names</span> <span class="o">=</span> <span class="n">enumeration</span><span class="o">.</span><span class="n">_member_names_</span>
|
|
<span class="n">member_values</span> <span class="o">=</span> <span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">value</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">enumeration</span><span class="p">]</span>
|
|
<span class="n">missing_names</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">missing_value</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">enumeration</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">member_names</span><span class="p">:</span>
|
|
<span class="c1"># not an alias</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">if</span> <span class="n">alias</span><span class="o">.</span><span class="n">value</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="c1"># negative numbers are not checked</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">values</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">_iter_bits_lsb</span><span class="p">(</span><span class="n">alias</span><span class="o">.</span><span class="n">value</span><span class="p">))</span>
|
|
<span class="n">missed</span> <span class="o">=</span> <span class="p">[</span><span class="n">v</span> <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">values</span> <span class="k">if</span> <span class="n">v</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">member_values</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">missed</span><span class="p">:</span>
|
|
<span class="n">missing_names</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">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">missed</span><span class="p">:</span>
|
|
<span class="n">missing_value</span> <span class="o">|=</span> <span class="n">val</span>
|
|
<span class="k">if</span> <span class="n">missing_names</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">missing_names</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="n">alias</span> <span class="o">=</span> <span class="s1">'alias </span><span class="si">%s</span><span class="s1"> is missing'</span> <span class="o">%</span> <span class="n">missing_names</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="n">alias</span> <span class="o">=</span> <span class="s1">'aliases </span><span class="si">%s</span><span class="s1"> and </span><span class="si">%s</span><span class="s1"> are missing'</span> <span class="o">%</span> <span class="p">(</span>
|
|
<span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">missing_names</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]),</span> <span class="n">missing_names</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">_is_single_bit</span><span class="p">(</span><span class="n">missing_value</span><span class="p">):</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="s1">'value 0x</span><span class="si">%x</span><span class="s1">'</span> <span class="o">%</span> <span class="n">missing_value</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="s1">'combined values of 0x</span><span class="si">%x</span><span class="s1">'</span> <span class="o">%</span> <span class="n">missing_value</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
|
<span class="s1">'invalid Flag </span><span class="si">%r</span><span class="s1">: </span><span class="si">%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1"> [use enum.show_flag_values(value) for details]'</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="n">alias</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">enumeration</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_test_simple_enum</span><span class="p">(</span><span class="n">checked_enum</span><span class="p">,</span> <span class="n">simple_enum</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> A function that can be used to test an enum created with :func:`_simple_enum`</span>
|
|
<span class="sd"> against the version created by subclassing :class:`Enum`::</span>
|
|
|
|
<span class="sd"> >>> from enum import Enum, _simple_enum, _test_simple_enum</span>
|
|
<span class="sd"> >>> @_simple_enum(Enum)</span>
|
|
<span class="sd"> ... class Color:</span>
|
|
<span class="sd"> ... RED = auto()</span>
|
|
<span class="sd"> ... GREEN = auto()</span>
|
|
<span class="sd"> ... BLUE = auto()</span>
|
|
<span class="sd"> >>> class CheckedColor(Enum):</span>
|
|
<span class="sd"> ... RED = auto()</span>
|
|
<span class="sd"> ... GREEN = auto()</span>
|
|
<span class="sd"> ... BLUE = auto()</span>
|
|
<span class="sd"> >>> _test_simple_enum(CheckedColor, Color)</span>
|
|
|
|
<span class="sd"> If differences are found, a :exc:`TypeError` is raised.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">failed</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">checked_enum</span><span class="o">.</span><span class="vm">__dict__</span> <span class="o">!=</span> <span class="n">simple_enum</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span>
|
|
<span class="n">checked_dict</span> <span class="o">=</span> <span class="n">checked_enum</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="n">checked_keys</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">checked_dict</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
|
|
<span class="n">simple_dict</span> <span class="o">=</span> <span class="n">simple_enum</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="n">simple_keys</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">simple_dict</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
|
|
<span class="n">member_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span>
|
|
<span class="nb">list</span><span class="p">(</span><span class="n">checked_enum</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
|
|
<span class="o">+</span> <span class="nb">list</span><span class="p">(</span><span class="n">simple_enum</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
|
|
<span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">(</span><span class="n">checked_keys</span> <span class="o">+</span> <span class="n">simple_keys</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'__module__'</span><span class="p">,</span> <span class="s1">'_member_map_'</span><span class="p">,</span> <span class="s1">'_value2member_map_'</span><span class="p">,</span> <span class="s1">'__doc__'</span><span class="p">,</span>
|
|
<span class="s1">'__static_attributes__'</span><span class="p">,</span> <span class="s1">'__firstlineno__'</span><span class="p">):</span>
|
|
<span class="c1"># keys known to be different, or very long</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">elif</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">member_names</span><span class="p">:</span>
|
|
<span class="c1"># members are checked below</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">elif</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">simple_keys</span><span class="p">:</span>
|
|
<span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"missing key: </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="p">))</span>
|
|
<span class="k">elif</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">checked_keys</span><span class="p">:</span>
|
|
<span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"extra key: </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="p">))</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">checked_value</span> <span class="o">=</span> <span class="n">checked_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
|
<span class="n">simple_value</span> <span class="o">=</span> <span class="n">simple_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="nb">callable</span><span class="p">(</span><span class="n">checked_value</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">checked_value</span><span class="p">,</span> <span class="n">bltns</span><span class="o">.</span><span class="n">property</span><span class="p">):</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s1">'__doc__'</span><span class="p">:</span>
|
|
<span class="c1"># remove all spaces/tabs</span>
|
|
<span class="n">compressed_checked_value</span> <span class="o">=</span> <span class="n">checked_value</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">' '</span><span class="p">,</span><span class="s1">''</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'</span><span class="se">\t</span><span class="s1">'</span><span class="p">,</span><span class="s1">''</span><span class="p">)</span>
|
|
<span class="n">compressed_simple_value</span> <span class="o">=</span> <span class="n">simple_value</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">' '</span><span class="p">,</span><span class="s1">''</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'</span><span class="se">\t</span><span class="s1">'</span><span class="p">,</span><span class="s1">''</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">compressed_checked_value</span> <span class="o">!=</span> <span class="n">compressed_simple_value</span><span class="p">:</span>
|
|
<span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2">:</span><span class="se">\n</span><span class="s2"> </span><span class="si">%s</span><span class="se">\n</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">key</span><span class="p">,</span>
|
|
<span class="s2">"checked -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">checked_value</span><span class="p">,</span> <span class="p">),</span>
|
|
<span class="s2">"simple -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">simple_value</span><span class="p">,</span> <span class="p">),</span>
|
|
<span class="p">))</span>
|
|
<span class="k">elif</span> <span class="n">checked_value</span> <span class="o">!=</span> <span class="n">simple_value</span><span class="p">:</span>
|
|
<span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2">:</span><span class="se">\n</span><span class="s2"> </span><span class="si">%s</span><span class="se">\n</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">key</span><span class="p">,</span>
|
|
<span class="s2">"checked -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">checked_value</span><span class="p">,</span> <span class="p">),</span>
|
|
<span class="s2">"simple -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">simple_value</span><span class="p">,</span> <span class="p">),</span>
|
|
<span class="p">))</span>
|
|
<span class="n">failed</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">member_names</span><span class="p">:</span>
|
|
<span class="n">failed_member</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">simple_keys</span><span class="p">:</span>
|
|
<span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'missing member from simple enum: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">checked_keys</span><span class="p">:</span>
|
|
<span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'extra member in simple enum: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">checked_member_dict</span> <span class="o">=</span> <span class="n">checked_enum</span><span class="p">[</span><span class="n">name</span><span class="p">]</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="n">checked_member_keys</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">checked_member_dict</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
|
|
<span class="n">simple_member_dict</span> <span class="o">=</span> <span class="n">simple_enum</span><span class="p">[</span><span class="n">name</span><span class="p">]</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="n">simple_member_keys</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">simple_member_dict</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
|
|
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">(</span><span class="n">checked_member_keys</span> <span class="o">+</span> <span class="n">simple_member_keys</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'__module__'</span><span class="p">,</span> <span class="s1">'__objclass__'</span><span class="p">,</span> <span class="s1">'_inverted_'</span><span class="p">):</span>
|
|
<span class="c1"># keys known to be different or absent</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">elif</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">simple_member_keys</span><span class="p">:</span>
|
|
<span class="n">failed_member</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"missing key </span><span class="si">%r</span><span class="s2"> not in the simple enum member </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">name</span><span class="p">))</span>
|
|
<span class="k">elif</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">checked_member_keys</span><span class="p">:</span>
|
|
<span class="n">failed_member</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"extra key </span><span class="si">%r</span><span class="s2"> in simple enum member </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</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="n">checked_value</span> <span class="o">=</span> <span class="n">checked_member_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
|
<span class="n">simple_value</span> <span class="o">=</span> <span class="n">simple_member_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">checked_value</span> <span class="o">!=</span> <span class="n">simple_value</span><span class="p">:</span>
|
|
<span class="n">failed_member</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2">:</span><span class="se">\n</span><span class="s2"> </span><span class="si">%s</span><span class="se">\n</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">key</span><span class="p">,</span>
|
|
<span class="s2">"checked member -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">checked_value</span><span class="p">,</span> <span class="p">),</span>
|
|
<span class="s2">"simple member -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">simple_value</span><span class="p">,</span> <span class="p">),</span>
|
|
<span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">failed_member</span><span class="p">:</span>
|
|
<span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1"> member mismatch:</span><span class="se">\n</span><span class="s1"> </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span>
|
|
<span class="n">name</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">failed_member</span><span class="p">),</span>
|
|
<span class="p">))</span>
|
|
<span class="k">for</span> <span class="n">method</span> <span class="ow">in</span> <span class="p">(</span>
|
|
<span class="s1">'__str__'</span><span class="p">,</span> <span class="s1">'__repr__'</span><span class="p">,</span> <span class="s1">'__reduce_ex__'</span><span class="p">,</span> <span class="s1">'__format__'</span><span class="p">,</span>
|
|
<span class="s1">'__getnewargs_ex__'</span><span class="p">,</span> <span class="s1">'__getnewargs__'</span><span class="p">,</span> <span class="s1">'__reduce_ex__'</span><span class="p">,</span> <span class="s1">'__reduce__'</span>
|
|
<span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">method</span> <span class="ow">in</span> <span class="n">simple_keys</span> <span class="ow">and</span> <span class="n">method</span> <span class="ow">in</span> <span class="n">checked_keys</span><span class="p">:</span>
|
|
<span class="c1"># cannot compare functions, and it exists in both, so we're good</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">elif</span> <span class="n">method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">simple_keys</span> <span class="ow">and</span> <span class="n">method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">checked_keys</span><span class="p">:</span>
|
|
<span class="c1"># method is inherited -- check it out</span>
|
|
<span class="n">checked_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">checked_enum</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">simple_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">simple_enum</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">checked_method</span><span class="p">,</span> <span class="s1">'__func__'</span><span class="p">):</span>
|
|
<span class="n">checked_method</span> <span class="o">=</span> <span class="n">checked_method</span><span class="o">.</span><span class="vm">__func__</span>
|
|
<span class="n">simple_method</span> <span class="o">=</span> <span class="n">simple_method</span><span class="o">.</span><span class="vm">__func__</span>
|
|
<span class="k">if</span> <span class="n">checked_method</span> <span class="o">!=</span> <span class="n">simple_method</span><span class="p">:</span>
|
|
<span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2">: </span><span class="si">%-30s</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">method</span><span class="p">,</span>
|
|
<span class="s2">"checked -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">checked_method</span><span class="p">,</span> <span class="p">),</span>
|
|
<span class="s2">"simple -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">simple_method</span><span class="p">,</span> <span class="p">),</span>
|
|
<span class="p">))</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># if the method existed in only one of the enums, it will have been caught</span>
|
|
<span class="c1"># in the first checks above</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">if</span> <span class="n">failed</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'enum mismatch:</span><span class="se">\n</span><span class="s1"> </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</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">failed</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_old_convert_</span><span class="p">(</span><span class="n">etype</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">module</span><span class="p">,</span> <span class="nb">filter</span><span class="p">,</span> <span class="n">source</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">boundary</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Create a new Enum subclass that replaces a collection of global constants</span>
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># convert all constants from source (or module) that pass filter() to</span>
|
|
<span class="c1"># a new Enum called name, and export the enum and its members back to</span>
|
|
<span class="c1"># module;</span>
|
|
<span class="c1"># also, replace the __reduce_ex__ method so unpickling works in</span>
|
|
<span class="c1"># previous Python versions</span>
|
|
<span class="n">module_globals</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="n">module</span><span class="p">]</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="k">if</span> <span class="n">source</span><span class="p">:</span>
|
|
<span class="n">source</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">source</span> <span class="o">=</span> <span class="n">module_globals</span>
|
|
<span class="c1"># _value2member_map_ is populated in the same order every time</span>
|
|
<span class="c1"># for a consistent reverse mapping of number to name when there</span>
|
|
<span class="c1"># are multiple names for the same number.</span>
|
|
<span class="n">members</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">source</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="nb">filter</span><span class="p">(</span><span class="n">name</span><span class="p">)]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># sort by value</span>
|
|
<span class="n">members</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">t</span><span class="p">:</span> <span class="p">(</span><span class="n">t</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="c1"># unless some values aren't comparable, in which case sort by name</span>
|
|
<span class="n">members</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">t</span><span class="p">:</span> <span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="n">etype</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">members</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="n">module</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="n">boundary</span> <span class="ow">or</span> <span class="n">KEEP</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="bp">cls</span>
|
|
|
|
<span class="n">_stdlib_enums</span> <span class="o">=</span> <span class="n">IntEnum</span><span class="p">,</span> <span class="n">StrEnum</span><span class="p">,</span> <span class="n">IntFlag</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="">enum</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> |