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.
Files changed (53) hide show
  1. datatypes/__init__.py +169 -0
  2. datatypes/collections/__init__.py +25 -0
  3. datatypes/collections/container.py +248 -0
  4. datatypes/collections/mapping.py +1226 -0
  5. datatypes/collections/sequence.py +311 -0
  6. datatypes/command.py +596 -0
  7. datatypes/compat.py +206 -0
  8. datatypes/config/__init__.py +13 -0
  9. datatypes/config/environ/__init__.py +33 -0
  10. datatypes/config/environ/base.py +332 -0
  11. datatypes/config/environ/token.py +173 -0
  12. datatypes/config/parser.py +256 -0
  13. datatypes/config/settings.py +352 -0
  14. datatypes/copy.py +151 -0
  15. datatypes/csv.py +547 -0
  16. datatypes/datetime.py +1243 -0
  17. datatypes/decorators/__init__.py +31 -0
  18. datatypes/decorators/base.py +449 -0
  19. datatypes/decorators/descriptor.py +490 -0
  20. datatypes/decorators/misc.py +152 -0
  21. datatypes/email.py +439 -0
  22. datatypes/enum.py +176 -0
  23. datatypes/event.py +299 -0
  24. datatypes/exception.py +13 -0
  25. datatypes/filetypes/__init__.py +10 -0
  26. datatypes/filetypes/html.py +540 -0
  27. datatypes/filetypes/toml.py +275 -0
  28. datatypes/http.py +1443 -0
  29. datatypes/logging.py +475 -0
  30. datatypes/number.py +586 -0
  31. datatypes/parse.py +362 -0
  32. datatypes/path.py +4358 -0
  33. datatypes/profile.py +246 -0
  34. datatypes/reflection/__init__.py +24 -0
  35. datatypes/reflection/inspect.py +3475 -0
  36. datatypes/reflection/other.py +843 -0
  37. datatypes/reflection/path.py +639 -0
  38. datatypes/server.py +642 -0
  39. datatypes/service.py +212 -0
  40. datatypes/ssh.py +812 -0
  41. datatypes/string.py +1632 -0
  42. datatypes/token/__init__.py +16 -0
  43. datatypes/token/abnf.py +1696 -0
  44. datatypes/token/base.py +921 -0
  45. datatypes/token/word.py +259 -0
  46. datatypes/typing.py +126 -0
  47. datatypes/url.py +988 -0
  48. datatypes/utils.py +179 -0
  49. datatypes-0.31.0.dist-info/METADATA +38 -0
  50. datatypes-0.31.0.dist-info/RECORD +53 -0
  51. datatypes-0.31.0.dist-info/WHEEL +5 -0
  52. datatypes-0.31.0.dist-info/licenses/LICENSE.txt +21 -0
  53. datatypes-0.31.0.dist-info/top_level.txt +1 -0
@@ -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
+