evennia/docs/5.x/_modules/distutils/version.html
2025-07-01 10:01:48 +02:00

454 lines
No EOL
39 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>distutils.version &#8212; Evennia latest documentation</title>
<link rel="stylesheet" href="../../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=d75fae25" />
<link rel="stylesheet" type="text/css" href="../../_static/nature.css?v=245aff17" />
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<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="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<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 latest</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">distutils.version</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<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>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for distutils.version</h1><div class="highlight"><pre>
<span></span><span class="c1">#</span>
<span class="c1"># distutils/version.py</span>
<span class="c1">#</span>
<span class="c1"># Implements multiple version numbering conventions for the</span>
<span class="c1"># Python Module Distribution Utilities.</span>
<span class="c1">#</span>
<span class="c1"># $Id$</span>
<span class="c1">#</span>
<span class="sd">&quot;&quot;&quot;Provides classes to represent module version numbers (one class for</span>
<span class="sd">each style of version numbering). There are currently two such classes</span>
<span class="sd">implemented: StrictVersion and LooseVersion.</span>
<span class="sd">Every version number class implements the following interface:</span>
<span class="sd"> * the &#39;parse&#39; method takes a string and parses it to some internal</span>
<span class="sd"> representation; if the string is an invalid version number,</span>
<span class="sd"> &#39;parse&#39; raises a ValueError exception</span>
<span class="sd"> * the class constructor takes an optional string argument which,</span>
<span class="sd"> if supplied, is passed to &#39;parse&#39;</span>
<span class="sd"> * __str__ reconstructs the string that was passed to &#39;parse&#39; (or</span>
<span class="sd"> an equivalent string -- ie. one that will generate an equivalent</span>
<span class="sd"> version number instance)</span>
<span class="sd"> * __repr__ generates Python code to recreate the version number instance</span>
<span class="sd"> * _cmp compares the current instance with either another instance</span>
<span class="sd"> of the same class or a string (which will be parsed to an instance</span>
<span class="sd"> of the same class, thus must follow the same rules)</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">contextlib</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">re</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">warnings</span>
<span class="nd">@contextlib</span><span class="o">.</span><span class="n">contextmanager</span>
<span class="k">def</span><span class="w"> </span><span class="nf">suppress_known_deprecation</span><span class="p">():</span>
<span class="k">with</span> <span class="n">warnings</span><span class="o">.</span><span class="n">catch_warnings</span><span class="p">(</span><span class="n">record</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="k">as</span> <span class="n">ctx</span><span class="p">:</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">filterwarnings</span><span class="p">(</span>
<span class="n">action</span><span class="o">=</span><span class="s1">&#39;default&#39;</span><span class="p">,</span>
<span class="n">category</span><span class="o">=</span><span class="ne">DeprecationWarning</span><span class="p">,</span>
<span class="n">message</span><span class="o">=</span><span class="s2">&quot;distutils Version classes are deprecated.&quot;</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">yield</span> <span class="n">ctx</span>
<span class="k">class</span><span class="w"> </span><span class="nc">Version</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Abstract base class for version numbering classes. Just provides</span>
<span class="sd"> constructor (__init__) and reproducer (__repr__), because those</span>
<span class="sd"> seem to be the same for all version numbering classes; and route</span>
<span class="sd"> rich comparisons to _cmp.</span>
<span class="sd"> &quot;&quot;&quot;</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">vstring</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">vstring</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">vstring</span><span class="p">)</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span>
<span class="s2">&quot;distutils Version classes are deprecated. Use packaging.version instead.&quot;</span><span class="p">,</span>
<span class="ne">DeprecationWarning</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="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="sa">f</span><span class="s2">&quot;</span><span class="si">{</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="si">}</span><span class="s2"> (&#39;</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2">&#39;)&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="n">c</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cmp</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">if</span> <span class="n">c</span> <span class="ow">is</span> <span class="bp">NotImplemented</span><span class="p">:</span>
<span class="k">return</span> <span class="n">c</span>
<span class="k">return</span> <span class="n">c</span> <span class="o">==</span> <span class="mi">0</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__lt__</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">c</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cmp</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">if</span> <span class="n">c</span> <span class="ow">is</span> <span class="bp">NotImplemented</span><span class="p">:</span>
<span class="k">return</span> <span class="n">c</span>
<span class="k">return</span> <span class="n">c</span> <span class="o">&lt;</span> <span class="mi">0</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__le__</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">c</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cmp</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">if</span> <span class="n">c</span> <span class="ow">is</span> <span class="bp">NotImplemented</span><span class="p">:</span>
<span class="k">return</span> <span class="n">c</span>
<span class="k">return</span> <span class="n">c</span> <span class="o">&lt;=</span> <span class="mi">0</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__gt__</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">c</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cmp</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">if</span> <span class="n">c</span> <span class="ow">is</span> <span class="bp">NotImplemented</span><span class="p">:</span>
<span class="k">return</span> <span class="n">c</span>
<span class="k">return</span> <span class="n">c</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__ge__</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">c</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cmp</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">if</span> <span class="n">c</span> <span class="ow">is</span> <span class="bp">NotImplemented</span><span class="p">:</span>
<span class="k">return</span> <span class="n">c</span>
<span class="k">return</span> <span class="n">c</span> <span class="o">&gt;=</span> <span class="mi">0</span>
<span class="c1"># Interface for version-number classes -- must be implemented</span>
<span class="c1"># by the following classes (the concrete ones -- Version should</span>
<span class="c1"># be treated as an abstract class).</span>
<span class="c1"># __init__ (string) - create and take same action as &#39;parse&#39;</span>
<span class="c1"># (string parameter is optional)</span>
<span class="c1"># parse (string) - convert a string representation to whatever</span>
<span class="c1"># internal representation is appropriate for</span>
<span class="c1"># this style of version numbering</span>
<span class="c1"># __str__ (self) - convert back to a string; should be very similar</span>
<span class="c1"># (if not identical to) the string supplied to parse</span>
<span class="c1"># __repr__ (self) - generate Python code to recreate</span>
<span class="c1"># the instance</span>
<span class="c1"># _cmp (self, other) - compare two version numbers (&#39;other&#39; may</span>
<span class="c1"># be an unparsed version string, or another</span>
<span class="c1"># instance of your version class)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">StrictVersion</span><span class="p">(</span><span class="n">Version</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Version numbering for anal retentives and software idealists.</span>
<span class="sd"> Implements the standard interface for version number classes as</span>
<span class="sd"> described above. A version number consists of two or three</span>
<span class="sd"> dot-separated numeric components, with an optional &quot;pre-release&quot; tag</span>
<span class="sd"> on the end. The pre-release tag consists of the letter &#39;a&#39; or &#39;b&#39;</span>
<span class="sd"> followed by a number. If the numeric components of two version</span>
<span class="sd"> numbers are equal, then one with a pre-release tag will always</span>
<span class="sd"> be deemed earlier (lesser) than one without.</span>
<span class="sd"> The following are valid version numbers (shown in the order that</span>
<span class="sd"> would be obtained by sorting according to the supplied cmp function):</span>
<span class="sd"> 0.4 0.4.0 (these two are equivalent)</span>
<span class="sd"> 0.4.1</span>
<span class="sd"> 0.5a1</span>
<span class="sd"> 0.5b3</span>
<span class="sd"> 0.5</span>
<span class="sd"> 0.9.6</span>
<span class="sd"> 1.0</span>
<span class="sd"> 1.0.4a3</span>
<span class="sd"> 1.0.4b1</span>
<span class="sd"> 1.0.4</span>
<span class="sd"> The following are examples of invalid version numbers:</span>
<span class="sd"> 1</span>
<span class="sd"> 2.7.2.2</span>
<span class="sd"> 1.3.a4</span>
<span class="sd"> 1.3pl1</span>
<span class="sd"> 1.3c4</span>
<span class="sd"> The rationale for this version numbering system will be explained</span>
<span class="sd"> in the distutils documentation.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">version_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span>
<span class="sa">r</span><span class="s1">&#39;^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$&#39;</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">VERBOSE</span> <span class="o">|</span> <span class="n">re</span><span class="o">.</span><span class="n">ASCII</span>
<span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">parse</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">vstring</span><span class="p">):</span>
<span class="n">match</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">version_re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">vstring</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;invalid version number &#39;</span><span class="si">{</span><span class="n">vstring</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span>
<span class="p">(</span><span class="n">major</span><span class="p">,</span> <span class="n">minor</span><span class="p">,</span> <span class="n">patch</span><span class="p">,</span> <span class="n">prerelease</span><span class="p">,</span> <span class="n">prerelease_num</span><span class="p">)</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">)</span>
<span class="k">if</span> <span class="n">patch</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">version</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="p">[</span><span class="n">major</span><span class="p">,</span> <span class="n">minor</span><span class="p">,</span> <span class="n">patch</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">version</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="p">[</span><span class="n">major</span><span class="p">,</span> <span class="n">minor</span><span class="p">]))</span> <span class="o">+</span> <span class="p">(</span><span class="mi">0</span><span class="p">,)</span>
<span class="k">if</span> <span class="n">prerelease</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">prerelease</span> <span class="o">=</span> <span class="p">(</span><span class="n">prerelease</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">int</span><span class="p">(</span><span class="n">prerelease_num</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">prerelease</span> <span class="o">=</span> <span class="kc">None</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">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">version</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">vstring</span> <span class="o">=</span> <span class="s1">&#39;.&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">version</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">2</span><span class="p">]))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">vstring</span> <span class="o">=</span> <span class="s1">&#39;.&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">version</span><span class="p">))</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">prerelease</span><span class="p">:</span>
<span class="n">vstring</span> <span class="o">=</span> <span class="n">vstring</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">prerelease</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">prerelease</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="k">return</span> <span class="n">vstring</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_cmp</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="k">with</span> <span class="n">suppress_known_deprecation</span><span class="p">():</span>
<span class="n">other</span> <span class="o">=</span> <span class="n">StrictVersion</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">StrictVersion</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">NotImplemented</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">version</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">version</span><span class="p">:</span>
<span class="c1"># versions match; pre-release drives the comparison</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cmp_prerelease</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">version</span> <span class="o">&lt;</span> <span class="n">other</span><span class="o">.</span><span class="n">version</span> <span class="k">else</span> <span class="mi">1</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_cmp_prerelease</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">&quot;&quot;&quot;</span>
<span class="sd"> case 1: self has prerelease, other doesn&#39;t; other is greater</span>
<span class="sd"> case 2: self doesn&#39;t have prerelease, other does: self is greater</span>
<span class="sd"> case 3: both or neither have prerelease: compare them!</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">prerelease</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">other</span><span class="o">.</span><span class="n">prerelease</span><span class="p">:</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">prerelease</span> <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">prerelease</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">prerelease</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">prerelease</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">prerelease</span> <span class="o">&lt;</span> <span class="n">other</span><span class="o">.</span><span class="n">prerelease</span><span class="p">:</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="c1"># end class StrictVersion</span>
<span class="c1"># The rules according to Greg Stein:</span>
<span class="c1"># 1) a version number has 1 or more numbers separated by a period or by</span>
<span class="c1"># sequences of letters. If only periods, then these are compared</span>
<span class="c1"># left-to-right to determine an ordering.</span>
<span class="c1"># 2) sequences of letters are part of the tuple for comparison and are</span>
<span class="c1"># compared lexicographically</span>
<span class="c1"># 3) recognize the numeric components may have leading zeroes</span>
<span class="c1">#</span>
<span class="c1"># The LooseVersion class below implements these rules: a version number</span>
<span class="c1"># string is split up into a tuple of integer and string components, and</span>
<span class="c1"># comparison is a simple tuple comparison. This means that version</span>
<span class="c1"># numbers behave in a predictable and obvious way, but a way that might</span>
<span class="c1"># not necessarily be how people *want* version numbers to behave. There</span>
<span class="c1"># wouldn&#39;t be a problem if people could stick to purely numeric version</span>
<span class="c1"># numbers: just split on period and compare the numbers as tuples.</span>
<span class="c1"># However, people insist on putting letters into their version numbers;</span>
<span class="c1"># the most common purpose seems to be:</span>
<span class="c1"># - indicating a &quot;pre-release&quot; version</span>
<span class="c1"># (&#39;alpha&#39;, &#39;beta&#39;, &#39;a&#39;, &#39;b&#39;, &#39;pre&#39;, &#39;p&#39;)</span>
<span class="c1"># - indicating a post-release patch (&#39;p&#39;, &#39;pl&#39;, &#39;patch&#39;)</span>
<span class="c1"># but of course this can&#39;t cover all version number schemes, and there&#39;s</span>
<span class="c1"># no way to know what a programmer means without asking him.</span>
<span class="c1">#</span>
<span class="c1"># The problem is what to do with letters (and other non-numeric</span>
<span class="c1"># characters) in a version number. The current implementation does the</span>
<span class="c1"># obvious and predictable thing: keep them as strings and compare</span>
<span class="c1"># lexically within a tuple comparison. This has the desired effect if</span>
<span class="c1"># an appended letter sequence implies something &quot;post-release&quot;:</span>
<span class="c1"># eg. &quot;0.99&quot; &lt; &quot;0.99pl14&quot; &lt; &quot;1.0&quot;, and &quot;5.001&quot; &lt; &quot;5.001m&quot; &lt; &quot;5.002&quot;.</span>
<span class="c1">#</span>
<span class="c1"># However, if letters in a version number imply a pre-release version,</span>
<span class="c1"># the &quot;obvious&quot; thing isn&#39;t correct. Eg. you would expect that</span>
<span class="c1"># &quot;1.5.1&quot; &lt; &quot;1.5.2a2&quot; &lt; &quot;1.5.2&quot;, but under the tuple/lexical comparison</span>
<span class="c1"># implemented here, this just isn&#39;t so.</span>
<span class="c1">#</span>
<span class="c1"># Two possible solutions come to mind. The first is to tie the</span>
<span class="c1"># comparison algorithm to a particular set of semantic rules, as has</span>
<span class="c1"># been done in the StrictVersion class above. This works great as long</span>
<span class="c1"># as everyone can go along with bondage and discipline. Hopefully a</span>
<span class="c1"># (large) subset of Python module programmers will agree that the</span>
<span class="c1"># particular flavour of bondage and discipline provided by StrictVersion</span>
<span class="c1"># provides enough benefit to be worth using, and will submit their</span>
<span class="c1"># version numbering scheme to its domination. The free-thinking</span>
<span class="c1"># anarchists in the lot will never give in, though, and something needs</span>
<span class="c1"># to be done to accommodate them.</span>
<span class="c1">#</span>
<span class="c1"># Perhaps a &quot;moderately strict&quot; version class could be implemented that</span>
<span class="c1"># lets almost anything slide (syntactically), and makes some heuristic</span>
<span class="c1"># assumptions about non-digits in version number strings. This could</span>
<span class="c1"># sink into special-case-hell, though; if I was as talented and</span>
<span class="c1"># idiosyncratic as Larry Wall, I&#39;d go ahead and implement a class that</span>
<span class="c1"># somehow knows that &quot;1.2.1&quot; &lt; &quot;1.2.2a2&quot; &lt; &quot;1.2.2&quot; &lt; &quot;1.2.2pl3&quot;, and is</span>
<span class="c1"># just as happy dealing with things like &quot;2g6&quot; and &quot;1.13++&quot;. I don&#39;t</span>
<span class="c1"># think I&#39;m smart enough to do it right though.</span>
<span class="c1">#</span>
<span class="c1"># In any case, I&#39;ve coded the test suite for this module (see</span>
<span class="c1"># ../test/test_version.py) specifically to fail on things like comparing</span>
<span class="c1"># &quot;1.2a2&quot; and &quot;1.2&quot;. That&#39;s not because the *code* is doing anything</span>
<span class="c1"># wrong, it&#39;s because the simple, obvious design doesn&#39;t match my</span>
<span class="c1"># complicated, hairy expectations for real-world version numbers. It</span>
<span class="c1"># would be a snap to fix the test suite to say, &quot;Yep, LooseVersion does</span>
<span class="c1"># the Right Thing&quot; (ie. the code matches the conception). But I&#39;d rather</span>
<span class="c1"># have a conception that matches common notions about version numbers.</span>
<div class="viewcode-block" id="LooseVersion">
<a class="viewcode-back" href="../../api/evennia.server.evennia_launcher.html#evennia.server.evennia_launcher.LooseVersion">[docs]</a>
<span class="k">class</span><span class="w"> </span><span class="nc">LooseVersion</span><span class="p">(</span><span class="n">Version</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Version numbering for anarchists and software realists.</span>
<span class="sd"> Implements the standard interface for version number classes as</span>
<span class="sd"> described above. A version number consists of a series of numbers,</span>
<span class="sd"> separated by either periods or strings of letters. When comparing</span>
<span class="sd"> version numbers, the numeric components will be compared</span>
<span class="sd"> numerically, and the alphabetic components lexically. The following</span>
<span class="sd"> are all valid version numbers, in no particular order:</span>
<span class="sd"> 1.5.1</span>
<span class="sd"> 1.5.2b2</span>
<span class="sd"> 161</span>
<span class="sd"> 3.10a</span>
<span class="sd"> 8.02</span>
<span class="sd"> 3.4j</span>
<span class="sd"> 1996.07.12</span>
<span class="sd"> 3.2.pl0</span>
<span class="sd"> 3.1.1.6</span>
<span class="sd"> 2g6</span>
<span class="sd"> 11g</span>
<span class="sd"> 0.960923</span>
<span class="sd"> 2.2beta29</span>
<span class="sd"> 1.13++</span>
<span class="sd"> 5.5.kw</span>
<span class="sd"> 2.0b1pl0</span>
<span class="sd"> In fact, there is no such thing as an invalid version number under</span>
<span class="sd"> this scheme; the rules for comparison are simple and predictable,</span>
<span class="sd"> but may not always give the results you want (for some definition</span>
<span class="sd"> of &quot;want&quot;).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">component_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;(\d+ | [a-z]+ | \.)&#39;</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">VERBOSE</span><span class="p">)</span>
<div class="viewcode-block" id="LooseVersion.parse">
<a class="viewcode-back" href="../../api/evennia.server.evennia_launcher.html#evennia.server.evennia_launcher.LooseVersion.parse">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">parse</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">vstring</span><span class="p">):</span>
<span class="c1"># I&#39;ve given up on thinking I can reconstruct the version string</span>
<span class="c1"># from the parsed tuple -- so I just store the string here for</span>
<span class="c1"># use by __str__</span>
<span class="bp">self</span><span class="o">.</span><span class="n">vstring</span> <span class="o">=</span> <span class="n">vstring</span>
<span class="n">components</span> <span class="o">=</span> <span class="p">[</span><span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">component_re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">vstring</span><span class="p">)</span> <span class="k">if</span> <span class="n">x</span> <span class="ow">and</span> <span class="n">x</span> <span class="o">!=</span> <span class="s1">&#39;.&#39;</span><span class="p">]</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">obj</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">components</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">components</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">obj</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="bp">self</span><span class="o">.</span><span class="n">version</span> <span class="o">=</span> <span class="n">components</span></div>
<span class="k">def</span><span class="w"> </span><span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">vstring</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="sa">f</span><span class="s2">&quot;LooseVersion (&#39;</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2">&#39;)&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_cmp</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">other</span> <span class="o">=</span> <span class="n">LooseVersion</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">LooseVersion</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">NotImplemented</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">version</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">version</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">version</span> <span class="o">&lt;</span> <span class="n">other</span><span class="o">.</span><span class="n">version</span><span class="p">:</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">version</span> <span class="o">&gt;</span> <span class="n">other</span><span class="o">.</span><span class="n">version</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">1</span></div>
<span class="c1"># end class LooseVersion</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<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 latest</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">distutils.version</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2024, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
</div>
</body>
</html>