datatypes 0.31.0__py3-none-any.whl
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.
- datatypes/__init__.py +169 -0
- datatypes/collections/__init__.py +25 -0
- datatypes/collections/container.py +248 -0
- datatypes/collections/mapping.py +1226 -0
- datatypes/collections/sequence.py +311 -0
- datatypes/command.py +596 -0
- datatypes/compat.py +206 -0
- datatypes/config/__init__.py +13 -0
- datatypes/config/environ/__init__.py +33 -0
- datatypes/config/environ/base.py +332 -0
- datatypes/config/environ/token.py +173 -0
- datatypes/config/parser.py +256 -0
- datatypes/config/settings.py +352 -0
- datatypes/copy.py +151 -0
- datatypes/csv.py +547 -0
- datatypes/datetime.py +1243 -0
- datatypes/decorators/__init__.py +31 -0
- datatypes/decorators/base.py +449 -0
- datatypes/decorators/descriptor.py +490 -0
- datatypes/decorators/misc.py +152 -0
- datatypes/email.py +439 -0
- datatypes/enum.py +176 -0
- datatypes/event.py +299 -0
- datatypes/exception.py +13 -0
- datatypes/filetypes/__init__.py +10 -0
- datatypes/filetypes/html.py +540 -0
- datatypes/filetypes/toml.py +275 -0
- datatypes/http.py +1443 -0
- datatypes/logging.py +475 -0
- datatypes/number.py +586 -0
- datatypes/parse.py +362 -0
- datatypes/path.py +4358 -0
- datatypes/profile.py +246 -0
- datatypes/reflection/__init__.py +24 -0
- datatypes/reflection/inspect.py +3475 -0
- datatypes/reflection/other.py +843 -0
- datatypes/reflection/path.py +639 -0
- datatypes/server.py +642 -0
- datatypes/service.py +212 -0
- datatypes/ssh.py +812 -0
- datatypes/string.py +1632 -0
- datatypes/token/__init__.py +16 -0
- datatypes/token/abnf.py +1696 -0
- datatypes/token/base.py +921 -0
- datatypes/token/word.py +259 -0
- datatypes/typing.py +126 -0
- datatypes/url.py +988 -0
- datatypes/utils.py +179 -0
- datatypes-0.31.0.dist-info/METADATA +38 -0
- datatypes-0.31.0.dist-info/RECORD +53 -0
- datatypes-0.31.0.dist-info/WHEEL +5 -0
- datatypes-0.31.0.dist-info/licenses/LICENSE.txt +21 -0
- datatypes-0.31.0.dist-info/top_level.txt +1 -0
datatypes/__init__.py
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from .collections import (
|
|
4
|
+
Pool,
|
|
5
|
+
Dict, Dict as Dictionary,
|
|
6
|
+
NormalizeMixin,
|
|
7
|
+
NamespaceMixin,
|
|
8
|
+
idict, idict as IDict, idict as Idict, idict as iDict,
|
|
9
|
+
AppendList,
|
|
10
|
+
SortedList, SortedList as OrderedList,
|
|
11
|
+
ListIterator,
|
|
12
|
+
Trie,
|
|
13
|
+
Namespace,
|
|
14
|
+
StackNamespace,
|
|
15
|
+
ContextNamespace,
|
|
16
|
+
HotSet,
|
|
17
|
+
Stack,
|
|
18
|
+
DictTree,
|
|
19
|
+
SortedSet, SortedSet as OrderedSet,
|
|
20
|
+
)
|
|
21
|
+
from .command import (
|
|
22
|
+
SimpleCommand,
|
|
23
|
+
Command,
|
|
24
|
+
Command as AsyncCommand, # DEPRECATED, use Command instead
|
|
25
|
+
ModuleCommand,
|
|
26
|
+
FileCommand,
|
|
27
|
+
)
|
|
28
|
+
from .config import (
|
|
29
|
+
Environ,
|
|
30
|
+
Config,
|
|
31
|
+
Settings,
|
|
32
|
+
MultiSettings,
|
|
33
|
+
)
|
|
34
|
+
from .copy import (
|
|
35
|
+
Deepcopy,
|
|
36
|
+
)
|
|
37
|
+
from .csv import (
|
|
38
|
+
CSVRow,
|
|
39
|
+
CSVRowDict,
|
|
40
|
+
CSV,
|
|
41
|
+
TempCSV,
|
|
42
|
+
)
|
|
43
|
+
from .datetime import (
|
|
44
|
+
Datetime,
|
|
45
|
+
ISO8601,
|
|
46
|
+
)
|
|
47
|
+
from .decorators import (
|
|
48
|
+
Decorator,
|
|
49
|
+
InstanceDecorator,
|
|
50
|
+
ClassDecorator,
|
|
51
|
+
FuncDecorator,
|
|
52
|
+
property,
|
|
53
|
+
cachedproperty, cachedproperty as cached_property,
|
|
54
|
+
classproperty,
|
|
55
|
+
method,
|
|
56
|
+
instancemethod,
|
|
57
|
+
classmethod,
|
|
58
|
+
staticmethod,
|
|
59
|
+
cache, cache as cached_method, cache as once,
|
|
60
|
+
deprecated,
|
|
61
|
+
)
|
|
62
|
+
from .email import (
|
|
63
|
+
Email,
|
|
64
|
+
)
|
|
65
|
+
from .enum import (
|
|
66
|
+
Enum,
|
|
67
|
+
)
|
|
68
|
+
from .event import (
|
|
69
|
+
Events,
|
|
70
|
+
)
|
|
71
|
+
from .filetypes import (
|
|
72
|
+
HTML,
|
|
73
|
+
HTMLCleaner,
|
|
74
|
+
TOML,
|
|
75
|
+
)
|
|
76
|
+
from .http import (
|
|
77
|
+
HTTPHeaders,
|
|
78
|
+
HTTPEnviron,
|
|
79
|
+
HTTPClient,
|
|
80
|
+
)
|
|
81
|
+
from .logging import (
|
|
82
|
+
LogMixin,
|
|
83
|
+
)
|
|
84
|
+
from .number import (
|
|
85
|
+
Binary,
|
|
86
|
+
Boolean, Boolean as Bool,
|
|
87
|
+
Hex,
|
|
88
|
+
Integer, Integer as Int,
|
|
89
|
+
Exponential,
|
|
90
|
+
Partitions,
|
|
91
|
+
Shorten,
|
|
92
|
+
)
|
|
93
|
+
from .parse import (
|
|
94
|
+
ArgvParser,
|
|
95
|
+
ArgParser,
|
|
96
|
+
Version,
|
|
97
|
+
)
|
|
98
|
+
from .path import (
|
|
99
|
+
Path,
|
|
100
|
+
Filepath,
|
|
101
|
+
Dirpath,
|
|
102
|
+
Imagepath,
|
|
103
|
+
TempFilepath, Filetemp,
|
|
104
|
+
TempDirpath, Dirtemp,
|
|
105
|
+
Cachepath,
|
|
106
|
+
Sentinel,
|
|
107
|
+
UrlFilepath,
|
|
108
|
+
SitePackagesDirpath,
|
|
109
|
+
DataDirpath,
|
|
110
|
+
)
|
|
111
|
+
from .profile import (
|
|
112
|
+
Profiler,
|
|
113
|
+
AggregateProfiler, AggregateProfiler as AProfiler
|
|
114
|
+
)
|
|
115
|
+
from .reflection import (
|
|
116
|
+
ClassFinder,
|
|
117
|
+
ClassKeyFinder,
|
|
118
|
+
ClasspathFinder,
|
|
119
|
+
MethodpathFinder,
|
|
120
|
+
ReflectCallable,
|
|
121
|
+
ReflectClass,
|
|
122
|
+
ReflectDocblock,
|
|
123
|
+
ReflectModule,
|
|
124
|
+
ReflectName,
|
|
125
|
+
ReflectPath,
|
|
126
|
+
ReflectType,
|
|
127
|
+
)
|
|
128
|
+
from .server import (
|
|
129
|
+
CallbackServer,
|
|
130
|
+
PathServer,
|
|
131
|
+
ServerThread,
|
|
132
|
+
ThreadingWSGIServer,
|
|
133
|
+
WSGIServer,
|
|
134
|
+
)
|
|
135
|
+
from .string import (
|
|
136
|
+
String, String as Str,
|
|
137
|
+
ByteString, ByteString as Bytes,
|
|
138
|
+
Base64,
|
|
139
|
+
NamingConvention,
|
|
140
|
+
EnglishWord,
|
|
141
|
+
Password,
|
|
142
|
+
)
|
|
143
|
+
from .token import (
|
|
144
|
+
# we don't import Token because it's too generic for toplevel, if you need
|
|
145
|
+
# it then import it directly from the submodule
|
|
146
|
+
Tokenizer,
|
|
147
|
+
Scanner,
|
|
148
|
+
WordTokenizer,
|
|
149
|
+
StopWordTokenizer,
|
|
150
|
+
ABNFParser,
|
|
151
|
+
ABNFGrammar,
|
|
152
|
+
)
|
|
153
|
+
from .url import (
|
|
154
|
+
Url,
|
|
155
|
+
Host, Host as ServerAddress,
|
|
156
|
+
Slug,
|
|
157
|
+
)
|
|
158
|
+
from .utils import (
|
|
159
|
+
cball,
|
|
160
|
+
cbany,
|
|
161
|
+
make_dict,
|
|
162
|
+
make_list,
|
|
163
|
+
Singleton,
|
|
164
|
+
infer_type,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
__version__ = "0.31.0"
|
|
169
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from .mapping import (
|
|
4
|
+
Dict,
|
|
5
|
+
DictTree,
|
|
6
|
+
idict,
|
|
7
|
+
Namespace,
|
|
8
|
+
StackNamespace,
|
|
9
|
+
ContextNamespace,
|
|
10
|
+
Pool,
|
|
11
|
+
NamespaceMixin,
|
|
12
|
+
NormalizeMixin,
|
|
13
|
+
)
|
|
14
|
+
from .sequence import (
|
|
15
|
+
AppendList,
|
|
16
|
+
ListIterator,
|
|
17
|
+
SortedList,
|
|
18
|
+
Stack,
|
|
19
|
+
)
|
|
20
|
+
from .container import (
|
|
21
|
+
HotSet,
|
|
22
|
+
SortedSet,
|
|
23
|
+
Trie,
|
|
24
|
+
)
|
|
25
|
+
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Container and membership like objects (eg, sets)
|
|
4
|
+
|
|
5
|
+
https://docs.python.org/3/library/collections.abc.html#collections.abc.Container
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from ..compat import *
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MembershipSet(set):
|
|
12
|
+
"""A set with all the AND, OR, and UNION operations disabled, making it
|
|
13
|
+
really only handy for testing membership
|
|
14
|
+
|
|
15
|
+
This is really more of a skeleton for the few times I've had to do this in
|
|
16
|
+
a project, usually we are implementing custom functionality that acts like
|
|
17
|
+
a set and so it will be nice to just be able to extend this and not have
|
|
18
|
+
to worry about disabling the unsupported methods
|
|
19
|
+
|
|
20
|
+
https://docs.python.org/3/library/stdtypes.html#set
|
|
21
|
+
|
|
22
|
+
If you need a readonly set, use frozenset:
|
|
23
|
+
https://docs.python.org/3/library/stdtypes.html#frozenset
|
|
24
|
+
"""
|
|
25
|
+
def __init__(self, iterable=None):
|
|
26
|
+
super().__init__()
|
|
27
|
+
|
|
28
|
+
if iterable:
|
|
29
|
+
self.update(iterable)
|
|
30
|
+
|
|
31
|
+
def discard(self, elem):
|
|
32
|
+
try:
|
|
33
|
+
self.remove(elem)
|
|
34
|
+
|
|
35
|
+
except KeyError:
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
# def add(self, elem):
|
|
39
|
+
# super().add(elem)
|
|
40
|
+
|
|
41
|
+
# def remove(self, elem):
|
|
42
|
+
# super().remove(elem)
|
|
43
|
+
|
|
44
|
+
# def clear(self):
|
|
45
|
+
# super().clear()
|
|
46
|
+
|
|
47
|
+
# def update(self, *others):
|
|
48
|
+
# for iterable in others:
|
|
49
|
+
# super().update(iterable)
|
|
50
|
+
|
|
51
|
+
def pop(self, *args, **kwargs):
|
|
52
|
+
raise NotImplementedError()
|
|
53
|
+
|
|
54
|
+
def __sub__(self, *args, **kwargs):
|
|
55
|
+
raise NotImplementedError()
|
|
56
|
+
|
|
57
|
+
def __and__(self, *args, **kwargs):
|
|
58
|
+
raise NotImplementedError()
|
|
59
|
+
|
|
60
|
+
def __or__(self, *args, **kwargs):
|
|
61
|
+
raise NotImplementedError()
|
|
62
|
+
|
|
63
|
+
def __xor__(self, *args, **kwargs):
|
|
64
|
+
raise NotImplementedError()
|
|
65
|
+
|
|
66
|
+
def __isub__(self, *args, **kwargs):
|
|
67
|
+
raise NotImplementedError()
|
|
68
|
+
|
|
69
|
+
def __iand__(self, *args, **kwargs):
|
|
70
|
+
raise NotImplementedError()
|
|
71
|
+
|
|
72
|
+
def __ior__(self, *args, **kwargs):
|
|
73
|
+
raise NotImplementedError()
|
|
74
|
+
|
|
75
|
+
def __ixor__(self, *args, **kwargs):
|
|
76
|
+
raise NotImplementedError()
|
|
77
|
+
|
|
78
|
+
def intersection_update(self, *args, **kwargs):
|
|
79
|
+
raise NotImplementedError()
|
|
80
|
+
|
|
81
|
+
def difference_update(self, *args, **kwargs):
|
|
82
|
+
raise NotImplementedError()
|
|
83
|
+
|
|
84
|
+
def symmetric_difference_update(self, *args, **kwargs):
|
|
85
|
+
raise NotImplementedError()
|
|
86
|
+
|
|
87
|
+
def symmetric_difference(self, *args, **kwargs):
|
|
88
|
+
raise NotImplementedError()
|
|
89
|
+
|
|
90
|
+
def difference(self, *args, **kwargs):
|
|
91
|
+
raise NotImplementedError()
|
|
92
|
+
|
|
93
|
+
def intersection(self, *args, **kwargs):
|
|
94
|
+
raise NotImplementedError()
|
|
95
|
+
|
|
96
|
+
def union(self, *args, **kwargs):
|
|
97
|
+
raise NotImplementedError()
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class SortedSet(MembershipSet):
|
|
101
|
+
"""An ordered set (a unique list)
|
|
102
|
+
|
|
103
|
+
This keeps the order that elements were added in, so basically it is like
|
|
104
|
+
a unique list, in fact, it could totally be called UniqueList. It is
|
|
105
|
+
similar to OrderedDict.keys
|
|
106
|
+
|
|
107
|
+
https://github.com/Jaymon/datatypes/issues/34
|
|
108
|
+
|
|
109
|
+
This implementation based on a doubly-linked list is more big-Oh efficient
|
|
110
|
+
than this implementation:
|
|
111
|
+
|
|
112
|
+
https://code.activestate.com/recipes/576694/
|
|
113
|
+
|
|
114
|
+
This implementation has O(1) for add and contains, but O(n) for remove
|
|
115
|
+
"""
|
|
116
|
+
def __init__(self, iterable=None, maxsize=None):
|
|
117
|
+
self.order = []
|
|
118
|
+
|
|
119
|
+
self.maxsize = maxsize if (maxsize and maxsize > 0) else None
|
|
120
|
+
|
|
121
|
+
super().__init__(iterable)
|
|
122
|
+
|
|
123
|
+
def update(self, *others):
|
|
124
|
+
for other in others:
|
|
125
|
+
for elem in other:
|
|
126
|
+
self.add(elem)
|
|
127
|
+
|
|
128
|
+
def add(self, elem):
|
|
129
|
+
if elem not in self:
|
|
130
|
+
super().add(elem)
|
|
131
|
+
self.order.append(elem)
|
|
132
|
+
self.added(elem)
|
|
133
|
+
|
|
134
|
+
def added(self, elem):
|
|
135
|
+
"""Called after elem is added to the set
|
|
136
|
+
|
|
137
|
+
This is handy if you want to do some post added manipulation of
|
|
138
|
+
the set
|
|
139
|
+
|
|
140
|
+
:param x: Any, the object added to the set
|
|
141
|
+
"""
|
|
142
|
+
if self.maxsize:
|
|
143
|
+
if len(self) > self.maxsize:
|
|
144
|
+
# elem wasn't in the set and we are now over max capacity so
|
|
145
|
+
# eject the oldest element
|
|
146
|
+
self.pop()
|
|
147
|
+
|
|
148
|
+
def remove(self, elem):
|
|
149
|
+
super().remove(elem)
|
|
150
|
+
self.order.remove(elem)
|
|
151
|
+
|
|
152
|
+
def pop(self):
|
|
153
|
+
"""Pop from the beginning of the set (this will always pop the oldest
|
|
154
|
+
item added to the set"""
|
|
155
|
+
try:
|
|
156
|
+
elem = self.order.pop(0)
|
|
157
|
+
super().remove(elem)
|
|
158
|
+
return elem
|
|
159
|
+
|
|
160
|
+
except IndexError as e:
|
|
161
|
+
raise KeyError("pop from an empty set") from e
|
|
162
|
+
|
|
163
|
+
def clear(self):
|
|
164
|
+
self.order = []
|
|
165
|
+
super().clear()
|
|
166
|
+
|
|
167
|
+
def __iter__(self):
|
|
168
|
+
"""iterate through the set in add order"""
|
|
169
|
+
yield from self.order
|
|
170
|
+
|
|
171
|
+
def __reversed__(self):
|
|
172
|
+
yield from reversed(self)
|
|
173
|
+
|
|
174
|
+
def full(self):
|
|
175
|
+
"""
|
|
176
|
+
https://docs.python.org/3/library/queue.html#queue.Queue.full
|
|
177
|
+
"""
|
|
178
|
+
return len(self) == self.maxsize
|
|
179
|
+
|
|
180
|
+
def empty(self):
|
|
181
|
+
"""
|
|
182
|
+
https://docs.python.org/3/library/queue.html#queue.Queue.empty
|
|
183
|
+
"""
|
|
184
|
+
return len(self) == 0
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class HotSet(SortedSet):
|
|
188
|
+
"""Holds maxsize unique elems and keeps it at that size, discarding
|
|
189
|
+
the oldest elem when a new elem is added once maxsize is reached"""
|
|
190
|
+
def __init__(self, maxsize=0):
|
|
191
|
+
super().__init__(maxsize=maxsize)
|
|
192
|
+
|
|
193
|
+
def add(self, elem):
|
|
194
|
+
if elem in self:
|
|
195
|
+
# elem is already in the list but we're going to refresh its
|
|
196
|
+
# ordering since elem has just been "touched"
|
|
197
|
+
self.order.remove(elem)
|
|
198
|
+
self.order.append(elem)
|
|
199
|
+
|
|
200
|
+
else:
|
|
201
|
+
super().add(elem)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
class Trie(object):
|
|
205
|
+
"""https://en.wikipedia.org/wiki/Trie"""
|
|
206
|
+
def __init__(self, *values):
|
|
207
|
+
self.values = {}
|
|
208
|
+
|
|
209
|
+
for value in values:
|
|
210
|
+
self.add(value)
|
|
211
|
+
|
|
212
|
+
def add(self, value):
|
|
213
|
+
if value:
|
|
214
|
+
ch = value[0]
|
|
215
|
+
remainder = value[1:]
|
|
216
|
+
if ch not in self.values:
|
|
217
|
+
self.values[ch] = None
|
|
218
|
+
|
|
219
|
+
if remainder:
|
|
220
|
+
if self.values[ch] is None:
|
|
221
|
+
self.values[ch] = type(self)(remainder)
|
|
222
|
+
|
|
223
|
+
else:
|
|
224
|
+
self.values[ch].add(self.normalize_value(remainder))
|
|
225
|
+
|
|
226
|
+
def has(self, value):
|
|
227
|
+
ret = True
|
|
228
|
+
ch = self.normalize_value(value[0])
|
|
229
|
+
remainder = value[1:]
|
|
230
|
+
if ch in self.values:
|
|
231
|
+
if remainder:
|
|
232
|
+
if self.values[ch] is None:
|
|
233
|
+
ret = False
|
|
234
|
+
else:
|
|
235
|
+
ret = self.values[ch].has(remainder)
|
|
236
|
+
|
|
237
|
+
else:
|
|
238
|
+
ret = False
|
|
239
|
+
|
|
240
|
+
#pout.v(ch, ret, self.values.keys())
|
|
241
|
+
return ret
|
|
242
|
+
|
|
243
|
+
def __contains__(self, value):
|
|
244
|
+
return self.has(value)
|
|
245
|
+
|
|
246
|
+
def normalize_value(self, value):
|
|
247
|
+
return value.lower()
|
|
248
|
+
|