plib3.stdlib 2.3.2__tar.gz → 2.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/CHANGES.rst +14 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/PKG-INFO +2 -8
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/README.rst +0 -4
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/__init__.py +1 -1
- plib3_stdlib-2.4.1/plib/stdlib/enumtools.py +217 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/__main__.py +1 -0
- plib3_stdlib-2.4.1/pyproject.toml +3 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/setup.cfg +1 -1
- plib3.stdlib-2.3.2/plib/stdlib/util/ModuleProxy.py +0 -183
- plib3.stdlib-2.3.2/plib/stdlib/util/__init__.py +0 -13
- plib3.stdlib-2.3.2/plib/test/stdlib/ModuleProxy_testmod.py +0 -29
- plib3.stdlib-2.3.2/plib/test/stdlib/test_ModuleProxy.py +0 -90
- plib3.stdlib-2.3.2/pyproject.toml +0 -3
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/LICENSE.txt +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/MANIFEST.in +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/TODO.rst +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/examples/pyget/pyget3.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/examples/pyidserver/pyidserver3.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/examples/scrips/scrips3.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/examples/tzname/tzname3.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/_extras.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/builtins.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/classtools.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/cmdline.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/coll/__init__.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/coll/_abc.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/coll/_bases.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/coll/_mixins.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/coll/_names.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/coll/_seq.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/coll/_tests.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/coll/_tuples.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/coll/_utils.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/copytools.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/csvtools.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/decotools/DelayedDecorator.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/decotools/IndexedGenerator.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/decotools/MemoizedGenerator.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/decotools/__init__.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/examples.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/fdtools.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/imp.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/ini/PIniFile.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/ini/PIniFileBase.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/ini/PIniFileOption.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/ini/PIniFileSection.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/ini/PIniInterface.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/ini/__init__.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/iters.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/jsontools.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/localize.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/mail.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/mathlib.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/net/__init__.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/net/client.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/net/transport.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/options.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/ostools.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/postinstall.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/proc.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/sigs.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/strings.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/systools.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/timer.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/stdlib/tztools.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/__main__.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/__init__.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/abstract_testlib.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib.txt +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_Singleton.txt +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_SortMixin.txt +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_abc.txt +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_builtins.txt +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_cached_property.txt +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_coll.txt +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_newlines.txt +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_normalize_slice.txt +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/mapping_testlib.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_abstractcontainer.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_abstractdict.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_abstractkeyed.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_abstractlist.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_abstractmapping.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_abstractsequence.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_basecontainer.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_basedict.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_basekeyed.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_baselist.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_basemapping.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_basesequence.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_ostools.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_sigs.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/test_stdlib.py +0 -0
- {plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/support/__init__.py +0 -0
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
plib3.stdlib Change Log
|
|
2
2
|
=======================
|
|
3
3
|
|
|
4
|
+
Version 2.4.1
|
|
5
|
+
-------------
|
|
6
|
+
|
|
7
|
+
- Remove tests related to ``ModuleProxy``.
|
|
8
|
+
|
|
9
|
+
Version 2.4
|
|
10
|
+
-----------
|
|
11
|
+
|
|
12
|
+
- Remove ``util`` sub-package with ``ModuleProxy`` class, no
|
|
13
|
+
longer needed in Python 3.8 or later since PEP 562 functionality
|
|
14
|
+
is available and fulfills the same purpose.
|
|
15
|
+
|
|
16
|
+
- Add requirement for Python 3.8 or later in ``setup.cfg``.
|
|
17
|
+
|
|
4
18
|
Version 2.3.2
|
|
5
19
|
-------------
|
|
6
20
|
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: plib3.stdlib
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.1
|
|
4
4
|
Summary: Useful packages and modules to extend the Python 3 standard library.
|
|
5
5
|
Home-page: http://pypi.org/project/plib3.stdlib
|
|
6
6
|
Author: Peter A. Donis
|
|
7
7
|
Author-email: peterdonis@alum.mit.edu
|
|
8
8
|
License: GPLv2
|
|
9
|
-
Platform: UNKNOWN
|
|
10
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
10
|
Classifier: Environment :: Console
|
|
12
11
|
Classifier: Environment :: MacOS X
|
|
@@ -19,6 +18,7 @@ Classifier: Operating System :: POSIX
|
|
|
19
18
|
Classifier: Operating System :: POSIX :: Linux
|
|
20
19
|
Classifier: Programming Language :: Python :: 3
|
|
21
20
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
22
|
Description-Content-Type: text/x-rst
|
|
23
23
|
License-File: LICENSE.txt
|
|
24
24
|
|
|
@@ -141,10 +141,6 @@ The following modules or sub-packages are available in the
|
|
|
141
141
|
based on those in the Python docs for the ``datetime`` module,
|
|
142
142
|
and a function to return the local system timezone name.
|
|
143
143
|
|
|
144
|
-
- The ``util`` sub-package provides the ``ModuleProxy`` class, which
|
|
145
|
-
is used by a number of PLIB3 sub-packages. See the docstrings
|
|
146
|
-
for the class and the sub-packages using it for more information.
|
|
147
|
-
|
|
148
144
|
Installation
|
|
149
145
|
------------
|
|
150
146
|
|
|
@@ -201,5 +197,3 @@ GNU General Public License for more details.
|
|
|
201
197
|
You should have received a copy of the GNU General Public License
|
|
202
198
|
along with this program; if not, write to the Free Software
|
|
203
199
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
204
|
-
|
|
205
|
-
|
|
@@ -117,10 +117,6 @@ The following modules or sub-packages are available in the
|
|
|
117
117
|
based on those in the Python docs for the ``datetime`` module,
|
|
118
118
|
and a function to return the local system timezone name.
|
|
119
119
|
|
|
120
|
-
- The ``util`` sub-package provides the ``ModuleProxy`` class, which
|
|
121
|
-
is used by a number of PLIB3 sub-packages. See the docstrings
|
|
122
|
-
for the class and the sub-packages using it for more information.
|
|
123
|
-
|
|
124
120
|
Installation
|
|
125
121
|
------------
|
|
126
122
|
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Module ENUMTOOLS -- PLIB3 Enum Enhancements
|
|
4
|
+
Sub-Package STDLIB of Package PLIB3
|
|
5
|
+
Copyright (C) 2008-2022 by Peter A. Donis
|
|
6
|
+
|
|
7
|
+
Released under the GNU General Public License, Version 2
|
|
8
|
+
See the LICENSE and README files for more information
|
|
9
|
+
|
|
10
|
+
This module contains enhanced Enum support; the main purpose
|
|
11
|
+
is to enable user-defined additions to an existing Enum.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import sys
|
|
15
|
+
from collections.abc import Mapping
|
|
16
|
+
import enum
|
|
17
|
+
|
|
18
|
+
from plib.stdlib.builtins import first
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _make_new_member(new_func, value_type, use_args):
|
|
22
|
+
# Code cribbed from EnumMeta.__new__, returns a function that
|
|
23
|
+
# constructs a new instance of the appropriate enum class
|
|
24
|
+
if use_args:
|
|
25
|
+
if issubclass(value_type, tuple):
|
|
26
|
+
def get_args(value):
|
|
27
|
+
return value
|
|
28
|
+
else:
|
|
29
|
+
def get_args(value):
|
|
30
|
+
return (value,)
|
|
31
|
+
def new_member(cls, value):
|
|
32
|
+
args = get_args(value)
|
|
33
|
+
member = new_func(cls, *args)
|
|
34
|
+
if not hasattr(member, '_value_'):
|
|
35
|
+
if value_type is object:
|
|
36
|
+
member._value_ = value
|
|
37
|
+
else:
|
|
38
|
+
member._value_ = value_type(*args)
|
|
39
|
+
return member
|
|
40
|
+
else:
|
|
41
|
+
def new_member(cls, value):
|
|
42
|
+
member = new_func(cls)
|
|
43
|
+
if not hasattr(member, '_value_'):
|
|
44
|
+
member._value_ = value
|
|
45
|
+
return member
|
|
46
|
+
return new_member
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ExtendableEnumMeta(enum.EnumMeta):
|
|
50
|
+
"""Metaclass for extendable enum.
|
|
51
|
+
|
|
52
|
+
Overrides class construction and ``__call__`` methods to allow new
|
|
53
|
+
instances to be created while still disallowing subclassing once
|
|
54
|
+
the enum has members.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
@classmethod
|
|
58
|
+
def __prepare__(meta, name, bases, **kwds):
|
|
59
|
+
# Note: this and what's in __new__ below seems like a lot of boilerplate to
|
|
60
|
+
# handle adding a keyword argument to a class definition (also it's not
|
|
61
|
+
# clear what exactly in EnumMeta.__prepare__ is checking for an unexpected
|
|
62
|
+
# keyword argument since **kwds is neither accessed nor passed in a super call)
|
|
63
|
+
disable_aliases = kwds.pop('disable_aliases', None)
|
|
64
|
+
classdict = enum.EnumMeta.__prepare__(name, bases, **kwds)
|
|
65
|
+
classdict._disable_aliases = disable_aliases
|
|
66
|
+
return classdict
|
|
67
|
+
|
|
68
|
+
def __new__(meta, name, bases, classdict, **kwds):
|
|
69
|
+
value_types = set(type(classdict[m]) for m in classdict._member_names)
|
|
70
|
+
if len(value_types) > 1:
|
|
71
|
+
raise ValueError("All members of an extendable enum must have the same value type.")
|
|
72
|
+
value_type = value_types.pop() if value_types else None
|
|
73
|
+
member_type, first_enum = meta._get_mixins_(name, bases)
|
|
74
|
+
new_func, _, use_args = meta._find_new_(
|
|
75
|
+
classdict, member_type, first_enum,
|
|
76
|
+
)
|
|
77
|
+
new_member = _make_new_member(new_func, value_type, use_args)
|
|
78
|
+
disable_aliases = classdict._disable_aliases
|
|
79
|
+
del classdict._disable_aliases
|
|
80
|
+
# Note: since we already popped it out of kwds in __prepare__ above,
|
|
81
|
+
# why is it still here?
|
|
82
|
+
assert kwds.pop('disable_aliases', None) is disable_aliases
|
|
83
|
+
enum_class = enum.EnumMeta.__new__(meta, name, bases, classdict, **kwds)
|
|
84
|
+
enum_class._value_type = value_type
|
|
85
|
+
enum_class._new_member = new_member
|
|
86
|
+
enum_class._disable_aliases = disable_aliases
|
|
87
|
+
return enum_class
|
|
88
|
+
|
|
89
|
+
def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1, disable_aliases=False):
|
|
90
|
+
enum_class = enum.EnumMeta.__call__(cls, value, names, module=module, qualname=qualname, type=type, start=start)
|
|
91
|
+
if names is not None:
|
|
92
|
+
# We created a new enum class
|
|
93
|
+
enum_class._disable_aliases = disable_aliases
|
|
94
|
+
return enum_class
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class ExtendableEnum(enum.Enum, metaclass=ExtendableEnumMeta):
|
|
98
|
+
"""Extendable enum class.
|
|
99
|
+
|
|
100
|
+
Allows user code to add new members to an existing enum by calling the
|
|
101
|
+
``add_member`` class method. The ``extend`` class method is also provided
|
|
102
|
+
for convenience to allow adding multiple new members at once. Once an
|
|
103
|
+
extendable enum has members it still cannot be subclassed.
|
|
104
|
+
|
|
105
|
+
>>> class Color(ExtendableEnum):
|
|
106
|
+
... RED = 1
|
|
107
|
+
... GREEN = 2
|
|
108
|
+
...
|
|
109
|
+
>>> Color.add_member('BLUE', 3)
|
|
110
|
+
<Color.BLUE: 3>
|
|
111
|
+
>>> Color.add_member('GREEN', 4)
|
|
112
|
+
Traceback (most recent call last):
|
|
113
|
+
...
|
|
114
|
+
ValueError: Member name GREEN already exists in enum Color
|
|
115
|
+
>>> Color.add_member('YELLOW', 2)
|
|
116
|
+
<Color.YELLOW: 2>
|
|
117
|
+
>>> class UniqueColor(ExtendableEnum, disable_aliases=True):
|
|
118
|
+
... RED = 1
|
|
119
|
+
... GREEN = 2
|
|
120
|
+
...
|
|
121
|
+
>>> UniqueColor.add_member('BLUE', 3)
|
|
122
|
+
<UniqueColor.BLUE: 3>
|
|
123
|
+
>>> UniqueColor.add_member('GREEN', 4)
|
|
124
|
+
Traceback (most recent call last):
|
|
125
|
+
...
|
|
126
|
+
ValueError: Member name GREEN already exists in enum UniqueColor
|
|
127
|
+
>>> UniqueColor.add_member('YELLOW', 2)
|
|
128
|
+
Traceback (most recent call last):
|
|
129
|
+
...
|
|
130
|
+
ValueError: Aliases are disabled for enum UniqueColor
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
@classmethod
|
|
134
|
+
def add_member(cls, name, value):
|
|
135
|
+
"""Add new member to an extendable enum.
|
|
136
|
+
|
|
137
|
+
Raises ``ValueError`` if a new member's value is not of the same type as
|
|
138
|
+
existing members' values, or if the member name already exists. If the
|
|
139
|
+
``disable_aliases`` keyword argument was used in constructing the extendable
|
|
140
|
+
enum class, existing values cannot be aliased, and ``ValueError`` is raised
|
|
141
|
+
if this is attempted.
|
|
142
|
+
"""
|
|
143
|
+
if not isinstance(value, cls._value_type):
|
|
144
|
+
raise ValueError("Invalid value type for extendable enum {}: {}".format(cls.__name__, repr(value)))
|
|
145
|
+
if name in cls.__members__:
|
|
146
|
+
raise ValueError("Member name {} already exists in enum {}".format(name, cls.__name__))
|
|
147
|
+
if cls._disable_aliases and (value in cls._value2member_map_):
|
|
148
|
+
raise ValueError("Aliases are disabled for enum {}".format(cls.__name__))
|
|
149
|
+
existing_member = first(m for m in cls.__members__.values() if m._value_ == value)
|
|
150
|
+
obj = cls._new_member(cls, value)
|
|
151
|
+
obj._name_ = name
|
|
152
|
+
obj._value_ = value
|
|
153
|
+
obj.__objclass__ = cls
|
|
154
|
+
cls._member_map_[name] = existing_member if existing_member is not None else obj
|
|
155
|
+
try:
|
|
156
|
+
# This will fail if value is not hashable, but enum supports that case so suppress exception
|
|
157
|
+
cls._value2member_map_[value] = existing_member if existing_member is not None else obj
|
|
158
|
+
except TypeError:
|
|
159
|
+
pass
|
|
160
|
+
if not existing_member:
|
|
161
|
+
# This list does not contain aliases
|
|
162
|
+
cls._member_names_.append(name)
|
|
163
|
+
return obj
|
|
164
|
+
|
|
165
|
+
@classmethod
|
|
166
|
+
def extend(cls, members):
|
|
167
|
+
"""Add multiple members at once to an extendable enum.
|
|
168
|
+
|
|
169
|
+
The ``members`` parameter must be an iterable of ``(name, value)`` tuples
|
|
170
|
+
or a mapping of names to values.
|
|
171
|
+
"""
|
|
172
|
+
for name, value in (members.items() if isinstance(members, Mapping) else members):
|
|
173
|
+
cls.add_member(name, value)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _get_transform(name, prefix_classname=False, classname_transform=None):
|
|
177
|
+
if prefix_classname:
|
|
178
|
+
prefix = name
|
|
179
|
+
if classname_transform:
|
|
180
|
+
prefix = classname_transform(prefix)
|
|
181
|
+
f = (lambda s: '{}_{}'.format(prefix, s))
|
|
182
|
+
else:
|
|
183
|
+
f = (lambda s: s)
|
|
184
|
+
return f
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _add_global(mod, s, m, f):
|
|
188
|
+
setattr(mod, f(s), m)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def add_enum_member_global(modname, s, m, prefix_classname=False, classname_transform=None):
|
|
192
|
+
"""Add global to module modname for enum member ``m`` with name ``s``.
|
|
193
|
+
"""
|
|
194
|
+
f = _get_transform(type(m).__name__, prefix_classname, classname_transform)
|
|
195
|
+
_add_global(sys.modules[modname], s, m, f)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def _add_globals(mod, name, obj, prefix_classname=False, classname_transform=None):
|
|
199
|
+
f = _get_transform(name, prefix_classname, classname_transform)
|
|
200
|
+
for s, m in obj.__members__.items():
|
|
201
|
+
_add_global(mod, s, m, f)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def add_enum_globals(modname, name, obj, prefix_classname=False, classname_transform=None):
|
|
205
|
+
"""Add globals to module ``modname`` for all members of enum with class name ``name``.
|
|
206
|
+
"""
|
|
207
|
+
return _add_globals(sys.modules[modname], name, obj, prefix_classname, classname_transform)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def add_all_enum_globals(modname, prefix_classname=False, classname_transform=None):
|
|
211
|
+
"""Add globals to module ``modname`` for all enums in module.
|
|
212
|
+
"""
|
|
213
|
+
mod = sys.modules[modname]
|
|
214
|
+
for name in dir(mod):
|
|
215
|
+
obj = getattr(mod, name)
|
|
216
|
+
if isinstance(obj, type) and issubclass(obj, enum.Enum):
|
|
217
|
+
_add_globals(mod, name, obj, prefix_classname, classname_transform)
|
|
@@ -23,6 +23,7 @@ classifiers =
|
|
|
23
23
|
Topic :: Software Development :: Libraries :: Python Modules
|
|
24
24
|
|
|
25
25
|
[options]
|
|
26
|
+
python_requires = >=3.8
|
|
26
27
|
packages =
|
|
27
28
|
plib
|
|
28
29
|
plib.stdlib
|
|
@@ -30,7 +31,6 @@ packages =
|
|
|
30
31
|
plib.stdlib.decotools
|
|
31
32
|
plib.stdlib.ini
|
|
32
33
|
plib.stdlib.net
|
|
33
|
-
plib.stdlib.util
|
|
34
34
|
plib.test
|
|
35
35
|
plib.test.stdlib
|
|
36
36
|
plib.test.support
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Module ModuleProxy
|
|
4
|
-
Sub-Package STDLIB.UTIL of Package PLIB3
|
|
5
|
-
Copyright (C) 2008-2022 by Peter A. Donis
|
|
6
|
-
|
|
7
|
-
Released under the GNU General Public License, Version 2
|
|
8
|
-
See the LICENSE and README files for more information
|
|
9
|
-
|
|
10
|
-
This module contains the ModuleProxy class. For examples
|
|
11
|
-
of intended use cases for this class, check out the
|
|
12
|
-
``main.py`` module in the PLIB3.GUI sub-package, or any
|
|
13
|
-
of a number of ``__init__.py`` modules in the PLIB3.IO
|
|
14
|
-
sub-packages. The docstrings and comments there give more
|
|
15
|
-
information.
|
|
16
|
-
|
|
17
|
-
One note about usage: whenever importing from a package
|
|
18
|
-
that uses this functionality, absolute imports should be
|
|
19
|
-
used. Using relative imports risks running afoul of the
|
|
20
|
-
name ambiguity between the object you want to import (a
|
|
21
|
-
class, usually) and the module it's defined in. Absolute
|
|
22
|
-
imports are "purer" anyway, so this is not viewed as a
|
|
23
|
-
bothersome restriction.
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
import sys
|
|
27
|
-
import os
|
|
28
|
-
import glob
|
|
29
|
-
import types
|
|
30
|
-
|
|
31
|
-
from plib.stdlib.imp import import_from_module
|
|
32
|
-
|
|
33
|
-
__all__ = ('ModuleProxy',)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
# Helper function for lazy loading of actual modules
|
|
37
|
-
|
|
38
|
-
def module_helper(pkgname, modname):
|
|
39
|
-
|
|
40
|
-
def f():
|
|
41
|
-
try:
|
|
42
|
-
return import_from_module(
|
|
43
|
-
'{}.{}'.format(pkgname, modname),
|
|
44
|
-
modname
|
|
45
|
-
)
|
|
46
|
-
except:
|
|
47
|
-
try:
|
|
48
|
-
# Try retrieving modname from pkgname as an attribute
|
|
49
|
-
# FIXME: why does this sometimes help? Nothing like
|
|
50
|
-
# this was needed in Python 2, and the advertised
|
|
51
|
-
# semantics of the above import_from_module call should
|
|
52
|
-
# mean that if the below works, the above should have!
|
|
53
|
-
return getattr(sys.modules.get(pkgname), modname)
|
|
54
|
-
except:
|
|
55
|
-
raise TypeError
|
|
56
|
-
|
|
57
|
-
f.__name__ = "{}_helper".format(modname)
|
|
58
|
-
return f
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
# Note that we subclass types.ModuleType in order to fool
|
|
62
|
-
# various introspection utilities (e.g., pydoc and the builtin
|
|
63
|
-
# 'help' command in the interpreter) into thinking ModuleProxy
|
|
64
|
-
# instances are actual modules. Among other things, this is
|
|
65
|
-
# necessary for the builtin 'help' command to properly display
|
|
66
|
-
# the info from the proxied module's docstring (setting the
|
|
67
|
-
# proxy's __doc__ to the actual module's __doc__ is *not*
|
|
68
|
-
# enough to do this by itself); note also that we don't
|
|
69
|
-
# override the constructor because various Python internals
|
|
70
|
-
# expect module objects to have a particular signature for
|
|
71
|
-
# the constructor; instead, we add the init_proxy method which
|
|
72
|
-
# must be called immediately on constructing the object to do
|
|
73
|
-
# the proxying magic
|
|
74
|
-
|
|
75
|
-
class ModuleProxy(types.ModuleType):
|
|
76
|
-
|
|
77
|
-
def init_proxy(self, name, path, globals_dict, locals_dict,
|
|
78
|
-
names=None, excludes=None, autodiscover=True):
|
|
79
|
-
|
|
80
|
-
self._excludes = excludes
|
|
81
|
-
|
|
82
|
-
names = dict(names or {})
|
|
83
|
-
excludes = set(excludes or [])
|
|
84
|
-
|
|
85
|
-
if autodiscover:
|
|
86
|
-
for pathname in path:
|
|
87
|
-
for filename in glob.glob(os.path.join(pathname, "*.py")):
|
|
88
|
-
modname = os.path.splitext(os.path.basename(filename))[0]
|
|
89
|
-
if not self._exclude(modname, excludes):
|
|
90
|
-
names[modname] = module_helper(name, modname)
|
|
91
|
-
|
|
92
|
-
self._names = names
|
|
93
|
-
self._realized_names = []
|
|
94
|
-
|
|
95
|
-
# Monkeypatch sys.modules with the proxy object (make
|
|
96
|
-
# sure we store a reference to the real module first!)
|
|
97
|
-
self._mod = sys.modules[name]
|
|
98
|
-
sys.modules[name] = self
|
|
99
|
-
|
|
100
|
-
# Pass-through module's docstring (this attribute name
|
|
101
|
-
# appears in both so __getattr__ below won't handle it);
|
|
102
|
-
# as noted above, this in itself isn't enough to make
|
|
103
|
-
# the 'help' builtin work right, but it is a necessary
|
|
104
|
-
# part of doing so
|
|
105
|
-
self.__doc__ = self._mod.__doc__
|
|
106
|
-
|
|
107
|
-
def __repr__(self):
|
|
108
|
-
return "<proxy of module '{}' from '{}'>".format(
|
|
109
|
-
self._mod.__name__, self._mod.__file__)
|
|
110
|
-
|
|
111
|
-
def _exclude(self, name, excludes):
|
|
112
|
-
# This allows customization of the exclusion algorithm; by
|
|
113
|
-
# default we exclude names in the excludes set and private
|
|
114
|
-
# names (ones that start with '_')
|
|
115
|
-
return (name in excludes) or name.startswith('_')
|
|
116
|
-
|
|
117
|
-
def _realize_name(self, name, value):
|
|
118
|
-
setattr(self, name, value) # so it gets retrieved without __getattr__
|
|
119
|
-
self._realized_names.append(name) # so __dir__ can see it
|
|
120
|
-
|
|
121
|
-
not_proxied = object()
|
|
122
|
-
|
|
123
|
-
def _get_name(self, name, module=None):
|
|
124
|
-
names = self.__dict__['_names']
|
|
125
|
-
result = names.get(name, self.not_proxied)
|
|
126
|
-
if result is not self.not_proxied:
|
|
127
|
-
|
|
128
|
-
if module is None:
|
|
129
|
-
# This hack allows features like 'lazy importing' to work;
|
|
130
|
-
# a callable names dict entry allows arbitrary (and possibly
|
|
131
|
-
# expensive) processing to take place only when the attribute
|
|
132
|
-
# is first accessed, instead of when the module is initially
|
|
133
|
-
# imported. Also, since we store the result in our __dict__,
|
|
134
|
-
# the expensive function won't get called again, so we are
|
|
135
|
-
# essentially memoizing the result.
|
|
136
|
-
try:
|
|
137
|
-
newresult = result()
|
|
138
|
-
except TypeError:
|
|
139
|
-
pass
|
|
140
|
-
else:
|
|
141
|
-
result = newresult
|
|
142
|
-
|
|
143
|
-
else:
|
|
144
|
-
# This can happen if the underlying sub-module was imported
|
|
145
|
-
# before we got a chance to proxy it
|
|
146
|
-
try:
|
|
147
|
-
newresult = getattr(module, name)
|
|
148
|
-
except AttributeError:
|
|
149
|
-
# It wasn't a proxied name after all (or else it isn't
|
|
150
|
-
# being proxied our way)
|
|
151
|
-
result = self.not_proxied
|
|
152
|
-
else:
|
|
153
|
-
result = newresult
|
|
154
|
-
|
|
155
|
-
if (result is not self.not_proxied) and (name in names):
|
|
156
|
-
assert name not in self._realized_names
|
|
157
|
-
self._realize_name(name, result)
|
|
158
|
-
del names[name] # no need to track it any more
|
|
159
|
-
|
|
160
|
-
return result
|
|
161
|
-
|
|
162
|
-
not_in_real_module = object()
|
|
163
|
-
|
|
164
|
-
def __getattr__(self, name):
|
|
165
|
-
# Remember we need to return the real module's attributes!
|
|
166
|
-
mod_result = getattr(self._mod, name, self.not_in_real_module)
|
|
167
|
-
if mod_result is self.not_in_real_module:
|
|
168
|
-
our_result = self._get_name(name)
|
|
169
|
-
if our_result is self.not_proxied:
|
|
170
|
-
raise AttributeError("{} object has no attribute {}".format(
|
|
171
|
-
self, name))
|
|
172
|
-
else:
|
|
173
|
-
return our_result
|
|
174
|
-
else:
|
|
175
|
-
if isinstance(mod_result, types.ModuleType):
|
|
176
|
-
# We might have gotten the underlying module for a proxied name
|
|
177
|
-
our_result = self._get_name(name, mod_result)
|
|
178
|
-
if (our_result is not self.not_proxied):
|
|
179
|
-
return our_result
|
|
180
|
-
return mod_result
|
|
181
|
-
|
|
182
|
-
def __dir__(self):
|
|
183
|
-
return sorted(dir(self._mod) + self._realized_names + list(self._names.keys()))
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Sub-Package STDLIB.UTIL of Package PLIB3
|
|
4
|
-
Copyright (C) 2008-2022 by Peter A. Donis
|
|
5
|
-
|
|
6
|
-
Released under the GNU General Public License, Version 2
|
|
7
|
-
See the LICENSE and README files for more information
|
|
8
|
-
|
|
9
|
-
This sub-package exposes the ModuleProxy class by itself,
|
|
10
|
-
to ensure that importing it brings in no other objects.
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
from .ModuleProxy import *
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
TEST.STDLIB.MODULEPROXY_TESTMOD.PY -- test module for ModuleProxy tests
|
|
4
|
-
Copyright (C) 2008-2022 by Peter A. Donis
|
|
5
|
-
|
|
6
|
-
Released under the GNU General Public License, Version 2
|
|
7
|
-
See the LICENSE and README files for more information
|
|
8
|
-
|
|
9
|
-
This is a test module for the unit tests of the ModuleProxy class.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
from plib.stdlib.util import ModuleProxy
|
|
13
|
-
|
|
14
|
-
test_var_static = "Static test variable."
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def _test_fn():
|
|
18
|
-
return "Function returning test value."
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
_names = {
|
|
22
|
-
'test_var_dynamic': "Dynamic test variable.",
|
|
23
|
-
'test_fn': _test_fn
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
ModuleProxy(__name__).init_proxy(__name__, None, globals(), locals(),
|
|
27
|
-
names=_names, autodiscover=False)
|
|
28
|
-
|
|
29
|
-
del _test_fn, _names
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
TEST.STDLIB.TEST_MODULEPROXY.PY -- test script for ModuleProxy
|
|
4
|
-
Copyright (C) 2008-2022 by Peter A. Donis
|
|
5
|
-
|
|
6
|
-
Released under the GNU General Public License, Version 2
|
|
7
|
-
See the LICENSE and README files for more information
|
|
8
|
-
|
|
9
|
-
This script contains unit tests for the ModuleProxy class in
|
|
10
|
-
the plib.stdlib sub-package.
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
import unittest
|
|
14
|
-
|
|
15
|
-
from plib.test.stdlib import ModuleProxy_testmod
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class ModuleProxyTest(unittest.TestCase):
|
|
19
|
-
|
|
20
|
-
def test_proxy(self):
|
|
21
|
-
testdir = dir(ModuleProxy_testmod)
|
|
22
|
-
testdict = set(ModuleProxy_testmod.__dict__.keys())
|
|
23
|
-
testnames = ModuleProxy_testmod._names
|
|
24
|
-
testmod = ModuleProxy_testmod._mod
|
|
25
|
-
|
|
26
|
-
# The dir function retrieves all attributes, including proxied ones
|
|
27
|
-
# that have not yet been realized
|
|
28
|
-
self.assertTrue('test_var_static' in testdir)
|
|
29
|
-
self.assertTrue('test_var_dynamic' in testdir)
|
|
30
|
-
self.assertTrue('test_fn' in testdir)
|
|
31
|
-
|
|
32
|
-
# The proxy module dict only contains realized attributes
|
|
33
|
-
self.assertTrue('test_var_static' not in testdict)
|
|
34
|
-
self.assertTrue('test_var_dynamic' not in testdict)
|
|
35
|
-
self.assertTrue('test_fn' not in testdict)
|
|
36
|
-
|
|
37
|
-
# The names dict only includes proxied attributes that need to be
|
|
38
|
-
# realized on first retrieval
|
|
39
|
-
self.assertTrue('test_var_static' not in testnames)
|
|
40
|
-
self.assertTrue('test_var_dynamic' in testnames)
|
|
41
|
-
self.assertTrue('test_fn' in testnames)
|
|
42
|
-
|
|
43
|
-
# The wrapped module only contains static attributes directly
|
|
44
|
-
self.assertTrue('test_var_static' in dir(testmod))
|
|
45
|
-
self.assertTrue('test_var_dynamic' not in dir(testmod))
|
|
46
|
-
self.assertTrue('test_fn' not in dir(testmod))
|
|
47
|
-
|
|
48
|
-
# Static attributes get retrieved directly from the wrapped module;
|
|
49
|
-
# nothing else changes behind the scenes
|
|
50
|
-
self.assertEqual(ModuleProxy_testmod.test_var_static, "Static test variable.")
|
|
51
|
-
self.assertEqual(testdir, dir(ModuleProxy_testmod))
|
|
52
|
-
self.assertTrue('test_var_static' in dir(ModuleProxy_testmod))
|
|
53
|
-
self.assertTrue('test_var_static' not in set(ModuleProxy_testmod.__dict__.keys()))
|
|
54
|
-
self.assertTrue('test_var_static' not in testnames)
|
|
55
|
-
self.assertTrue('test_var_static' in dir(testmod))
|
|
56
|
-
|
|
57
|
-
# Dynamic attributes get retrieved from the names dict, and are
|
|
58
|
-
# removed from it and put directly on the proxy module to speed
|
|
59
|
-
# up subsequent retrievals
|
|
60
|
-
self.assertEqual(ModuleProxy_testmod.test_var_dynamic, "Dynamic test variable.")
|
|
61
|
-
self.assertEqual(testdir, dir(ModuleProxy_testmod))
|
|
62
|
-
self.assertTrue('test_var_dynamic' in dir(ModuleProxy_testmod))
|
|
63
|
-
self.assertTrue('test_var_dynamic' in set(ModuleProxy_testmod.__dict__.keys()))
|
|
64
|
-
self.assertTrue('test_var_dynamic' not in testnames)
|
|
65
|
-
self.assertTrue('test_var_dynamic' not in dir(testmod))
|
|
66
|
-
|
|
67
|
-
# Dynamic attributes that are callable work the same as above, except
|
|
68
|
-
# that they get called first and the result is returned as the attribute value
|
|
69
|
-
self.assertEqual(ModuleProxy_testmod.test_fn, "Function returning test value.")
|
|
70
|
-
self.assertEqual(testdir, dir(ModuleProxy_testmod))
|
|
71
|
-
self.assertTrue('test_fn' in dir(ModuleProxy_testmod))
|
|
72
|
-
self.assertTrue('test_fn' in set(ModuleProxy_testmod.__dict__.keys()))
|
|
73
|
-
self.assertTrue('test_fn' not in testnames)
|
|
74
|
-
self.assertTrue('test_fn' not in dir(testmod))
|
|
75
|
-
|
|
76
|
-
testdir = dir(ModuleProxy_testmod)
|
|
77
|
-
testdict = set(ModuleProxy_testmod.__dict__.keys())
|
|
78
|
-
testnames = dict(ModuleProxy_testmod._names)
|
|
79
|
-
testmoddir = dir(ModuleProxy_testmod._mod)
|
|
80
|
-
|
|
81
|
-
# A nonexistent attribute leaves everything unchanged after retrieval is attempted
|
|
82
|
-
self.assertRaises(AttributeError, getattr, ModuleProxy_testmod, 'this_one_aint_there')
|
|
83
|
-
self.assertEqual(testdir, dir(ModuleProxy_testmod))
|
|
84
|
-
self.assertEqual(testdict, set(ModuleProxy_testmod.__dict__.keys()))
|
|
85
|
-
self.assertEqual(testnames, ModuleProxy_testmod._names)
|
|
86
|
-
self.assertEqual(testmoddir, dir(ModuleProxy_testmod._mod))
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if __name__ == '__main__':
|
|
90
|
-
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_Singleton.txt
RENAMED
|
File without changes
|
{plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_SortMixin.txt
RENAMED
|
File without changes
|
|
File without changes
|
{plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_builtins.txt
RENAMED
|
File without changes
|
{plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_cached_property.txt
RENAMED
|
File without changes
|
|
File without changes
|
{plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_newlines.txt
RENAMED
|
File without changes
|
{plib3.stdlib-2.3.2 → plib3_stdlib-2.4.1}/plib/test/stdlib/doctests/test_stdlib_normalize_slice.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|