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/token/word.py
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from ..compat import *
|
|
4
|
+
from ..string import String
|
|
5
|
+
from .base import Token, Tokenizer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class WordToken(Token):
|
|
9
|
+
"""This is what is returned from the Tokenizer and contains pointers to the
|
|
10
|
+
left deliminator and the right deliminator, and also the actual token
|
|
11
|
+
|
|
12
|
+
.ldelim - the deliminators to the left of the token
|
|
13
|
+
.text - the actual token value that was found
|
|
14
|
+
.rdelim - the deliminators to the right of the token
|
|
15
|
+
"""
|
|
16
|
+
def __init__(self, tokenizer, text, start, stop, ldelim=None, rdelim=None):
|
|
17
|
+
super().__init__(tokenizer, start, stop)
|
|
18
|
+
self.text = text
|
|
19
|
+
self.ldelim = ldelim
|
|
20
|
+
self.rdelim = rdelim
|
|
21
|
+
|
|
22
|
+
def __str__(self):
|
|
23
|
+
return self.text
|
|
24
|
+
|
|
25
|
+
def __pout__(self):
|
|
26
|
+
"""used by pout python external library
|
|
27
|
+
|
|
28
|
+
https://github.com/Jaymon/pout
|
|
29
|
+
"""
|
|
30
|
+
tokens = (
|
|
31
|
+
'"{}"'.format(self.ldelim.text) if self.ldelim else None,
|
|
32
|
+
'"{}"'.format(self.text),
|
|
33
|
+
'"{}"'.format(self.rdelim.text) if self.rdelim else None,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
return "{} <- {} -> {}".format(tokens[0], tokens[1], tokens[2])
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class WordTokenizer(Tokenizer):
|
|
40
|
+
"""Tokenize a string finding tokens that are divided by passed in
|
|
41
|
+
characters
|
|
42
|
+
"""
|
|
43
|
+
DEFAULT_CHARS = String.WHITESPACE + String.PUNCTUATION
|
|
44
|
+
"""If no deliminators are passed into the constructor then use these"""
|
|
45
|
+
|
|
46
|
+
token_class = WordToken
|
|
47
|
+
"""The token class this class will use to create Token instances"""
|
|
48
|
+
|
|
49
|
+
def __init__(self, buffer, chars=None):
|
|
50
|
+
"""
|
|
51
|
+
:param buffer: str|io.IOBase, passed through to parent
|
|
52
|
+
:param chars: callable|str|set, if a callback, it should have the
|
|
53
|
+
signature: callback(char) and return True if the char is a delim,
|
|
54
|
+
False otherwise. If a string then it is a string of chars that will
|
|
55
|
+
be considered delims
|
|
56
|
+
"""
|
|
57
|
+
if not chars:
|
|
58
|
+
chars = self.DEFAULT_CHARS
|
|
59
|
+
|
|
60
|
+
if chars and not callable(chars):
|
|
61
|
+
chars = set(chars)
|
|
62
|
+
|
|
63
|
+
self.chars = chars
|
|
64
|
+
|
|
65
|
+
super().__init__(buffer)
|
|
66
|
+
|
|
67
|
+
def is_delim_char(self, ch):
|
|
68
|
+
ret = False
|
|
69
|
+
chars = self.chars
|
|
70
|
+
if chars:
|
|
71
|
+
if callable(chars):
|
|
72
|
+
ret = chars(ch)
|
|
73
|
+
|
|
74
|
+
else:
|
|
75
|
+
ret = ch in chars
|
|
76
|
+
|
|
77
|
+
return ret
|
|
78
|
+
|
|
79
|
+
def tell_ldelim(self):
|
|
80
|
+
"""Tell the current ldelim start position, this is mainly used
|
|
81
|
+
internally
|
|
82
|
+
|
|
83
|
+
:returns: int, the cursor position of the start of the left deliminator
|
|
84
|
+
of the current token
|
|
85
|
+
"""
|
|
86
|
+
pos = self.buffer.tell()
|
|
87
|
+
ch = self.buffer.read(1)
|
|
88
|
+
if not ch:
|
|
89
|
+
# EOF, stream is exhausted
|
|
90
|
+
raise StopIteration()
|
|
91
|
+
|
|
92
|
+
if self.is_delim_char(ch):
|
|
93
|
+
p = pos
|
|
94
|
+
while self.is_delim_char(ch):
|
|
95
|
+
p -= 1
|
|
96
|
+
if p >= 0:
|
|
97
|
+
self.buffer.seek(p)
|
|
98
|
+
ch = self.buffer.read(1)
|
|
99
|
+
|
|
100
|
+
else:
|
|
101
|
+
break
|
|
102
|
+
|
|
103
|
+
if p >= 0:
|
|
104
|
+
p += 1
|
|
105
|
+
else:
|
|
106
|
+
p = 0
|
|
107
|
+
pos = p
|
|
108
|
+
|
|
109
|
+
else:
|
|
110
|
+
p = pos
|
|
111
|
+
while not self.is_delim_char(ch):
|
|
112
|
+
p -= 1
|
|
113
|
+
if p >= 0:
|
|
114
|
+
self.buffer.seek(p)
|
|
115
|
+
ch = self.buffer.read(1)
|
|
116
|
+
|
|
117
|
+
else:
|
|
118
|
+
break
|
|
119
|
+
|
|
120
|
+
if p >= 0:
|
|
121
|
+
self.buffer.seek(p)
|
|
122
|
+
pos = self.tell_ldelim()
|
|
123
|
+
|
|
124
|
+
else:
|
|
125
|
+
pos = -1
|
|
126
|
+
|
|
127
|
+
return pos
|
|
128
|
+
|
|
129
|
+
def next(self):
|
|
130
|
+
"""Get the next Token
|
|
131
|
+
|
|
132
|
+
:returns: Token, the next token found in .stream
|
|
133
|
+
"""
|
|
134
|
+
ldelim = token = rdelim = None
|
|
135
|
+
|
|
136
|
+
start = self.tell_ldelim()
|
|
137
|
+
|
|
138
|
+
# find the left deliminator
|
|
139
|
+
if start >= 0:
|
|
140
|
+
text = ""
|
|
141
|
+
self.buffer.seek(start)
|
|
142
|
+
ch = self.buffer.read(1)
|
|
143
|
+
|
|
144
|
+
while self.is_delim_char(ch):
|
|
145
|
+
text += ch
|
|
146
|
+
ch = self.buffer.read(1)
|
|
147
|
+
|
|
148
|
+
stop = self.buffer.tell() - 1
|
|
149
|
+
ldelim = self.token_class(self, text, start, stop)
|
|
150
|
+
start = stop
|
|
151
|
+
|
|
152
|
+
else:
|
|
153
|
+
start = 0
|
|
154
|
+
self.buffer.seek(start)
|
|
155
|
+
ch = self.buffer.read(1)
|
|
156
|
+
|
|
157
|
+
# find the actual token
|
|
158
|
+
if ch:
|
|
159
|
+
text = ""
|
|
160
|
+
while ch and not self.is_delim_char(ch):
|
|
161
|
+
text += ch
|
|
162
|
+
ch = self.buffer.read(1)
|
|
163
|
+
|
|
164
|
+
stop = self.buffer.tell() - 1
|
|
165
|
+
token = self.token_class(self, text, start, stop)
|
|
166
|
+
start = stop
|
|
167
|
+
|
|
168
|
+
# find the right deliminator
|
|
169
|
+
if ch:
|
|
170
|
+
text = ""
|
|
171
|
+
while self.is_delim_char(ch):
|
|
172
|
+
text += ch
|
|
173
|
+
ch = self.buffer.read(1)
|
|
174
|
+
|
|
175
|
+
stop = self.buffer.tell() - 1
|
|
176
|
+
|
|
177
|
+
# we're one character ahead, so we want to move back one
|
|
178
|
+
self.buffer.seek(stop)
|
|
179
|
+
|
|
180
|
+
rdelim = self.token_class(self, text, start, stop)
|
|
181
|
+
|
|
182
|
+
if not token:
|
|
183
|
+
raise StopIteration()
|
|
184
|
+
|
|
185
|
+
token.ldelim = ldelim
|
|
186
|
+
token.rdelim = rdelim
|
|
187
|
+
|
|
188
|
+
return self.normalize(token)
|
|
189
|
+
|
|
190
|
+
def prev(self):
|
|
191
|
+
"""Returns the previous Token
|
|
192
|
+
|
|
193
|
+
:returns: Token, the previous token found in the stream, None if there
|
|
194
|
+
are no previous tokens
|
|
195
|
+
"""
|
|
196
|
+
token = None
|
|
197
|
+
try:
|
|
198
|
+
start = self.tell_ldelim()
|
|
199
|
+
|
|
200
|
+
except StopIteration:
|
|
201
|
+
self.buffer.seek(self.buffer.tell() - 1)
|
|
202
|
+
start = self.tell_ldelim()
|
|
203
|
+
token = self.next()
|
|
204
|
+
|
|
205
|
+
else:
|
|
206
|
+
if start > 0:
|
|
207
|
+
self.buffer.seek(start - 1)
|
|
208
|
+
start = self.tell_ldelim()
|
|
209
|
+
token = self.next()
|
|
210
|
+
|
|
211
|
+
if not token:
|
|
212
|
+
raise StopIteration()
|
|
213
|
+
|
|
214
|
+
start = token.ldelim.start if token.ldelim else token.start
|
|
215
|
+
self.buffer.seek(start)
|
|
216
|
+
|
|
217
|
+
return self.normalize(token)
|
|
218
|
+
|
|
219
|
+
def normalize(self, token):
|
|
220
|
+
return token
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
class StopWordTokenizer(WordTokenizer):
|
|
224
|
+
"""Strips stop words from a string"""
|
|
225
|
+
|
|
226
|
+
# This list comes from Plancast's Formatting.php library (2010-2-4)
|
|
227
|
+
STOP_WORDS = set([
|
|
228
|
+
'a', 'about', 'above', 'after', 'again', 'against', 'all', 'am', 'an',
|
|
229
|
+
'and', 'any', 'are', 'as', 'at', 'be', 'because', 'been', 'before',
|
|
230
|
+
'being', 'below', 'between', 'both', 'but', 'by', 'did', 'do', 'does',
|
|
231
|
+
'doing', 'down', 'during', 'each', 'few', 'for', 'from', 'further',
|
|
232
|
+
'had', 'has', 'have', 'having', 'he', 'her', 'here', 'hers', 'herself',
|
|
233
|
+
'him', 'himself', 'his', 'how', 'i', 'if', 'in', 'into', 'is', 'it',
|
|
234
|
+
'its', 'itself', 'me', 'more', 'most', 'my', 'myself', 'no', 'nor',
|
|
235
|
+
'not', 'of', 'off', 'on', 'once', 'only', 'or', 'other', 'our', 'ours',
|
|
236
|
+
'ourselves', 'out', 'over', 'own', 'same', 'she', 'so', 'some', 'such',
|
|
237
|
+
'than', 'that', 'the', 'their', 'theirs', 'them', 'themselves', 'then',
|
|
238
|
+
'there', 'these', 'they', 'this', 'those', 'through', 'to', 'too',
|
|
239
|
+
'under', 'until', 'up', 'very', 'was', 'we', 'were', 'what', 'when',
|
|
240
|
+
'where', 'which', 'while', 'who', 'whom', 'why', 'with', 'you', 'your',
|
|
241
|
+
'yours', 'yourself', 'yourselves',
|
|
242
|
+
])
|
|
243
|
+
|
|
244
|
+
def next(self):
|
|
245
|
+
while True:
|
|
246
|
+
t = super().next()
|
|
247
|
+
if self.is_valid(t):
|
|
248
|
+
return t
|
|
249
|
+
|
|
250
|
+
def prev(self):
|
|
251
|
+
while True:
|
|
252
|
+
t = super().prev()
|
|
253
|
+
if (t is None) or self.is_valid(t):
|
|
254
|
+
return t
|
|
255
|
+
|
|
256
|
+
def is_valid(self, t):
|
|
257
|
+
word = t.text.lower()
|
|
258
|
+
return word not in self.STOP_WORDS
|
|
259
|
+
|
datatypes/typing.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Typing hints in one place, I keep having to remember where certain annotations
|
|
3
|
+
are located to import them, hopefully I'll be able to use this as a source
|
|
4
|
+
of truth
|
|
5
|
+
|
|
6
|
+
https://github.com/python/typeshed - Typeshed contains external type
|
|
7
|
+
annotations for the Python standard library and Python builtins
|
|
8
|
+
|
|
9
|
+
https://docs.python.org/3/library/typing.html#user-defined-generic-types
|
|
10
|
+
Good overview on how to define custom classes so they can accept annotations
|
|
11
|
+
and use those annotations throughout the class to make sure they expect the
|
|
12
|
+
correct type
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# https://docs.python.org/3/library/typing.html
|
|
16
|
+
from typing import (
|
|
17
|
+
TypeVar,
|
|
18
|
+
NewType, # https://docs.python.org/3/library/typing.html#typing.NewType
|
|
19
|
+
TypeVarTuple, # https://docs.python.org/3/library/typing.html#typing.TypeVarTuple
|
|
20
|
+
|
|
21
|
+
T, # https://docs.python.org/3/library/typing.html#generics
|
|
22
|
+
Generic, # https://docs.python.org/3/library/typing.html#typing.Generic
|
|
23
|
+
Any,
|
|
24
|
+
LiteralString,
|
|
25
|
+
Literal,
|
|
26
|
+
NoReturn, Never,
|
|
27
|
+
|
|
28
|
+
# represents current enclosed class
|
|
29
|
+
#https://docs.python.org/3/library/typing.html#typing.Self
|
|
30
|
+
Self,
|
|
31
|
+
Protocol,
|
|
32
|
+
|
|
33
|
+
Union,
|
|
34
|
+
Optional,
|
|
35
|
+
ClassVar,
|
|
36
|
+
Final, # https://docs.python.org/3/library/typing.html#typing.Final
|
|
37
|
+
|
|
38
|
+
# Dict with typing info for keys/values
|
|
39
|
+
# https://docs.python.org/3/library/typing.html#typing.TypedDict
|
|
40
|
+
TypedDict,
|
|
41
|
+
Required,
|
|
42
|
+
NotRequired,
|
|
43
|
+
#ReadOnly, # py 3.13+ https://docs.python.org/3/library/typing.html#typing.ReadOnly
|
|
44
|
+
|
|
45
|
+
# tuple version of TypedDict
|
|
46
|
+
NamedTuple, # https://docs.python.org/3/library/typing.html#typing.NamedTuple
|
|
47
|
+
|
|
48
|
+
Annotated, # https://docs.python.org/3/library/typing.html#typing.Annotated
|
|
49
|
+
#TypeIs, # https://docs.python.org/3/library/typing.html#typing.TypeIs
|
|
50
|
+
TypeGuard,
|
|
51
|
+
|
|
52
|
+
# https://docs.python.org/3/library/typing.html#abcs-and-protocols-for-working-with-i-o
|
|
53
|
+
IO,
|
|
54
|
+
TextIO,
|
|
55
|
+
BinaryIO,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# https://docs.python.org/3/library/types.html
|
|
60
|
+
from types import (
|
|
61
|
+
NoneType,
|
|
62
|
+
FunctionType,
|
|
63
|
+
LambdaType,
|
|
64
|
+
GeneratorType,
|
|
65
|
+
CoroutineType,
|
|
66
|
+
AsyncGeneratorType,
|
|
67
|
+
MethodType,
|
|
68
|
+
EllipsisType,
|
|
69
|
+
UnionType,
|
|
70
|
+
FrameType,
|
|
71
|
+
CodeType,
|
|
72
|
+
ModuleType,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# https://docs.python.org/3/library/contextlib.html
|
|
77
|
+
#
|
|
78
|
+
# You should use these instead of the typing versions, as described in:
|
|
79
|
+
# https://docs.python.org/3/library/typing.html#aliases-to-contextlib-abcs
|
|
80
|
+
from contextlib import (
|
|
81
|
+
AbstractContextManager,
|
|
82
|
+
AbstractAsyncContextManager,
|
|
83
|
+
ContextDecorator,
|
|
84
|
+
AsyncContextDecorator,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# https://docs.python.org/3/library/typing.html#abcs-and-protocols-for-working-with-i-o
|
|
89
|
+
# from typing import (
|
|
90
|
+
# IO,
|
|
91
|
+
# TextIO,
|
|
92
|
+
# BinaryIO,
|
|
93
|
+
# )
|
|
94
|
+
|
|
95
|
+
# https://docs.python.org/3/library/io.html
|
|
96
|
+
# from io import (
|
|
97
|
+
# IOBase,
|
|
98
|
+
# TextIOBase,
|
|
99
|
+
# )
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# https://docs.python.org/3/library/collections.abc.html
|
|
103
|
+
from collections.abc import (
|
|
104
|
+
Container,
|
|
105
|
+
Hashable,
|
|
106
|
+
Iterable, # use this for things that just need to be iterated from 0...N
|
|
107
|
+
Iterator,
|
|
108
|
+
Reversible,
|
|
109
|
+
Generator, # https://docs.python.org/3/library/typing.html#annotating-generators-and-coroutines
|
|
110
|
+
AsyncIterable,
|
|
111
|
+
AsyncIterator,
|
|
112
|
+
AsyncGenerator,
|
|
113
|
+
Sized,
|
|
114
|
+
Callable, # callbacks, first arg is arguments, second is return type
|
|
115
|
+
Collection,
|
|
116
|
+
Sequence,
|
|
117
|
+
MutableSequence,
|
|
118
|
+
Set,
|
|
119
|
+
MutableSet,
|
|
120
|
+
Mapping, # base class for dict-like behavior
|
|
121
|
+
MutableMapping,
|
|
122
|
+
Awaitable,
|
|
123
|
+
Coroutine,
|
|
124
|
+
Buffer,
|
|
125
|
+
)
|
|
126
|
+
|