datatypes 0.12.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 +153 -0
- datatypes/collections/__init__.py +22 -0
- datatypes/collections/container.py +150 -0
- datatypes/collections/mapping.py +614 -0
- datatypes/collections/sequence.py +469 -0
- datatypes/command.py +572 -0
- datatypes/compat.py +205 -0
- datatypes/config/__init__.py +9 -0
- datatypes/config/environ.py +302 -0
- datatypes/config/parser.py +255 -0
- datatypes/copy.py +151 -0
- datatypes/csv.py +322 -0
- datatypes/datetime.py +888 -0
- datatypes/decorators/__init__.py +23 -0
- datatypes/decorators/base.py +343 -0
- datatypes/decorators/descriptor.py +389 -0
- datatypes/decorators/misc.py +118 -0
- datatypes/email.py +351 -0
- datatypes/enum.py +191 -0
- datatypes/event.py +207 -0
- datatypes/filetypes/__init__.py +12 -0
- datatypes/filetypes/html.py +556 -0
- datatypes/filetypes/toml.py +260 -0
- datatypes/http.py +723 -0
- datatypes/logging.py +384 -0
- datatypes/number.py +187 -0
- datatypes/parse.py +246 -0
- datatypes/path.py +3637 -0
- datatypes/profile.py +232 -0
- datatypes/reflection.py +1498 -0
- datatypes/server.py +408 -0
- datatypes/service.py +212 -0
- datatypes/string.py +1328 -0
- datatypes/token/__init__.py +16 -0
- datatypes/token/abnf.py +1704 -0
- datatypes/token/base.py +475 -0
- datatypes/token/word.py +259 -0
- datatypes/url.py +841 -0
- datatypes/utils.py +142 -0
- datatypes-0.12.0.dist-info/LICENSE.txt +21 -0
- datatypes-0.12.0.dist-info/METADATA +52 -0
- datatypes-0.12.0.dist-info/RECORD +44 -0
- datatypes-0.12.0.dist-info/WHEEL +5 -0
- datatypes-0.12.0.dist-info/top_level.txt +1 -0
datatypes/compat.py
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from __future__ import unicode_literals, division, print_function, absolute_import
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
import cPickle as pickle
|
|
7
|
+
except ImportError:
|
|
8
|
+
import pickle
|
|
9
|
+
|
|
10
|
+
# shamelessly ripped from https://github.com/kennethreitz/requests/blob/master/requests/compat.py
|
|
11
|
+
# Syntax sugar.
|
|
12
|
+
_ver = sys.version_info
|
|
13
|
+
is_py2 = _ver[0] == 2
|
|
14
|
+
is_py3 = _ver[0] == 3
|
|
15
|
+
|
|
16
|
+
if is_py2:
|
|
17
|
+
basestring = basestring
|
|
18
|
+
unicode = unicode
|
|
19
|
+
range = xrange # range is now always an iterator
|
|
20
|
+
input = raw_input
|
|
21
|
+
cmp = cmp
|
|
22
|
+
|
|
23
|
+
import Queue as queue
|
|
24
|
+
|
|
25
|
+
# using _* makes __all__ not export this automatically, so you have to
|
|
26
|
+
# explicitly import this (from datatypes.compat import _thread), the reason
|
|
27
|
+
# is because the thread module is lowkey deprecated in favor of the
|
|
28
|
+
# threading module
|
|
29
|
+
#
|
|
30
|
+
# https://stackoverflow.com/questions/1141047/why-was-the-thread-module-renamed-to-thread-in-python-3-x
|
|
31
|
+
#
|
|
32
|
+
# I've chosen to keep the _thread syntax to prod me into finding a better
|
|
33
|
+
# way to do something, but I still have access to it explicitely if I need it
|
|
34
|
+
import thread as _thread
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
from cStringIO import StringIO
|
|
38
|
+
except ImportError:
|
|
39
|
+
from StringIO import StringIO
|
|
40
|
+
|
|
41
|
+
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
|
42
|
+
from BaseHTTPServer import (
|
|
43
|
+
BaseHTTPRequestHandler,
|
|
44
|
+
HTTPServer,
|
|
45
|
+
)
|
|
46
|
+
import SocketServer as socketserver
|
|
47
|
+
import Cookie as cookies
|
|
48
|
+
import __builtin__ as builtins
|
|
49
|
+
|
|
50
|
+
from urllib import urlencode
|
|
51
|
+
from urllib2 import (
|
|
52
|
+
Request,
|
|
53
|
+
urlopen,
|
|
54
|
+
URLError,
|
|
55
|
+
HTTPError,
|
|
56
|
+
)
|
|
57
|
+
import urlparse as parse
|
|
58
|
+
|
|
59
|
+
import itertools
|
|
60
|
+
zip = itertools.izip
|
|
61
|
+
zip_longest = itertools.izip_longest
|
|
62
|
+
|
|
63
|
+
from collections import (
|
|
64
|
+
Iterable,
|
|
65
|
+
Mapping,
|
|
66
|
+
Callable,
|
|
67
|
+
MutableSequence,
|
|
68
|
+
Sequence,
|
|
69
|
+
Collection,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
from HTMLParser import HTMLParser
|
|
74
|
+
#unescape = HTMLParser().unescape
|
|
75
|
+
|
|
76
|
+
import cgi
|
|
77
|
+
class html(object):
|
|
78
|
+
@classmethod
|
|
79
|
+
def escape(cls, *args, **kwargs):
|
|
80
|
+
return cgi.escape(*args, **kwargs)
|
|
81
|
+
|
|
82
|
+
@classmethod
|
|
83
|
+
def unescape(cls, *args, **kwargs):
|
|
84
|
+
return HTMLParser().unescape(*args, **kwargs)
|
|
85
|
+
|
|
86
|
+
# NOTE -- getargspace isn't a full mapping of getfullargspec
|
|
87
|
+
from inspect import getargspec as getfullargspec
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
exec("""def reraise(exception_class, e, traceback=None):
|
|
91
|
+
try:
|
|
92
|
+
raise exception_class, e, traceback
|
|
93
|
+
finally:
|
|
94
|
+
traceback = None
|
|
95
|
+
""")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
else:
|
|
99
|
+
basestring = (str, bytes)
|
|
100
|
+
unicode = str
|
|
101
|
+
long = int
|
|
102
|
+
input = input
|
|
103
|
+
|
|
104
|
+
import queue
|
|
105
|
+
import _thread
|
|
106
|
+
from io import StringIO
|
|
107
|
+
from http.server import (
|
|
108
|
+
HTTPServer,
|
|
109
|
+
SimpleHTTPRequestHandler,
|
|
110
|
+
BaseHTTPRequestHandler,
|
|
111
|
+
)
|
|
112
|
+
import socketserver
|
|
113
|
+
from http import cookies
|
|
114
|
+
import builtins
|
|
115
|
+
|
|
116
|
+
from functools import reduce # removed from common functions
|
|
117
|
+
from html.parser import HTMLParser
|
|
118
|
+
from urllib import parse
|
|
119
|
+
from urllib.parse import urlencode
|
|
120
|
+
from urllib.request import Request, urlopen
|
|
121
|
+
from urllib.error import URLError, HTTPError
|
|
122
|
+
try:
|
|
123
|
+
import html
|
|
124
|
+
#from html import unescape
|
|
125
|
+
except ImportError:
|
|
126
|
+
import cgi
|
|
127
|
+
class html(object):
|
|
128
|
+
@classmethod
|
|
129
|
+
def escape(cls, *args, **kwargs):
|
|
130
|
+
return cgi.escape(*args, **kwargs)
|
|
131
|
+
|
|
132
|
+
@classmethod
|
|
133
|
+
def unescape(cls, *args, **kwargs):
|
|
134
|
+
return HTMLParser().unescape(*args, **kwargs)
|
|
135
|
+
#unescape = HTMLParser.unescape
|
|
136
|
+
|
|
137
|
+
from inspect import getfullargspec
|
|
138
|
+
from itertools import zip_longest
|
|
139
|
+
|
|
140
|
+
from collections.abc import (
|
|
141
|
+
Iterable,
|
|
142
|
+
Mapping,
|
|
143
|
+
Callable,
|
|
144
|
+
MutableSequence,
|
|
145
|
+
Sequence,
|
|
146
|
+
Collection,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
# ripped from six https://github.com/benjaminp/six
|
|
151
|
+
def reraise(exception_class, e, traceback=None):
|
|
152
|
+
"""the 3 params correspond to the return value of sys.exc_info()
|
|
153
|
+
|
|
154
|
+
https://docs.python.org/3/library/sys.html#sys.exc_info
|
|
155
|
+
|
|
156
|
+
:param exception_class: BaseException, the class of the exception to reraise
|
|
157
|
+
:param e: BaseException instance, the actual exception instance
|
|
158
|
+
:param traceback: traceback, the stack trace
|
|
159
|
+
"""
|
|
160
|
+
try:
|
|
161
|
+
e = exception_class("" if e is None else e)
|
|
162
|
+
if e.__traceback__ is not traceback:
|
|
163
|
+
raise e.with_traceback(traceback)
|
|
164
|
+
raise e
|
|
165
|
+
finally:
|
|
166
|
+
e = None
|
|
167
|
+
traceback = None
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# py3 has no cmp function for some strange reason
|
|
171
|
+
# https://codegolf.stackexchange.com/a/49779
|
|
172
|
+
def cmp(a, b):
|
|
173
|
+
return (a > b) - (a < b)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
Str = unicode if is_py2 else str
|
|
177
|
+
Bytes = str if is_py2 else bytes
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
# TODO using reraise
|
|
181
|
+
|
|
182
|
+
# if py_2:
|
|
183
|
+
# #raise error_info[0].__class__, error_info[0], error_info[1][2]
|
|
184
|
+
# reraise(*error_info)
|
|
185
|
+
# #raise error_info[0].__class__, error_info[1], error_info[2]
|
|
186
|
+
#
|
|
187
|
+
# elif py_3:
|
|
188
|
+
# #e, exc_info = error_info
|
|
189
|
+
# #et, ei, tb = exc_info
|
|
190
|
+
#
|
|
191
|
+
# reraise(*error_info)
|
|
192
|
+
# #et, ei, tb = error_info
|
|
193
|
+
# #raise ei.with_traceback(tb)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
# if not error_info:
|
|
197
|
+
# exc_info = sys.exc_info()
|
|
198
|
+
# #raise e.__class__, e, exc_info[2]
|
|
199
|
+
# #self.error_info = (e, exc_info)
|
|
200
|
+
# self.error_info = exc_info
|
|
201
|
+
#
|
|
202
|
+
# if error_info:
|
|
203
|
+
#
|
|
204
|
+
# reraise(*error_info)
|
|
205
|
+
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import os
|
|
3
|
+
import tempfile
|
|
4
|
+
|
|
5
|
+
from ..compat import *
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Environ(Mapping):
|
|
9
|
+
"""Create an Environ namespace instance
|
|
10
|
+
|
|
11
|
+
you would usually create this like this:
|
|
12
|
+
|
|
13
|
+
environ = Environ("PREFIX_")
|
|
14
|
+
|
|
15
|
+
Then you can access any environment variables with that prefix from the
|
|
16
|
+
`environ` instance.
|
|
17
|
+
|
|
18
|
+
:Example:
|
|
19
|
+
# in your environment
|
|
20
|
+
export PREFIX_FOOBAR=1
|
|
21
|
+
export PREFIX_CHE="this is the che value"
|
|
22
|
+
|
|
23
|
+
# in your python code
|
|
24
|
+
environ = Environ("PREFIX_")
|
|
25
|
+
|
|
26
|
+
print(environ.FOOBAR) # "1"
|
|
27
|
+
print(environ.CHE) # this is the che value
|
|
28
|
+
|
|
29
|
+
# by default, all environ values are string, but you can set defaults
|
|
30
|
+
# and set the type
|
|
31
|
+
environ.setdefault("BAZ", 1000, type=int)
|
|
32
|
+
|
|
33
|
+
print(environ.BAZ, type(environ.BAZ)) # 1000 <class 'int'>
|
|
34
|
+
"""
|
|
35
|
+
@classmethod
|
|
36
|
+
def find_namespace(cls, prefix):
|
|
37
|
+
namespace = ""
|
|
38
|
+
if prefix:
|
|
39
|
+
namespace = prefix.split(".", maxsplit=1)[0].upper()
|
|
40
|
+
if not namespace.endswith("_"):
|
|
41
|
+
namespace += "_"
|
|
42
|
+
return namespace
|
|
43
|
+
|
|
44
|
+
def __init__(self, namespace="", environ=None):
|
|
45
|
+
"""
|
|
46
|
+
:param namespace: str, usually __name__ from the calling module but can
|
|
47
|
+
also be "PREFIX_" or something like that
|
|
48
|
+
:param environ: str, the environment you want this instance to wrap, it
|
|
49
|
+
defualts to os.environ
|
|
50
|
+
"""
|
|
51
|
+
self.__dict__["namespace"] = self.find_namespace(namespace)
|
|
52
|
+
self.__dict__["defaults"] = {}
|
|
53
|
+
self.__dict__["environ"] = environ or os.environ
|
|
54
|
+
|
|
55
|
+
def setdefault(self, key, value, type=None):
|
|
56
|
+
self.defaults[self.ekey(key)] = {
|
|
57
|
+
"value": value,
|
|
58
|
+
"type": type,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
def set(self, key, value):
|
|
62
|
+
self.__setattr__(key, value)
|
|
63
|
+
#os.environ[self.key(key)] = value
|
|
64
|
+
|
|
65
|
+
def __setattr__(self, key, value):
|
|
66
|
+
#os.environ[self.key(key)] = value
|
|
67
|
+
self.environ[self.key(key)] = value
|
|
68
|
+
|
|
69
|
+
def __setitem__(self, key, value):
|
|
70
|
+
self.__setattr__(key, value)
|
|
71
|
+
|
|
72
|
+
def nset(self, key, values):
|
|
73
|
+
"""Given a list of values, this will set key_* where * is 1 -> len(values)
|
|
74
|
+
|
|
75
|
+
:param key: string, the key that will be added to the environment as key_*
|
|
76
|
+
:param values: list, a list of values
|
|
77
|
+
"""
|
|
78
|
+
self.ndelete(key)
|
|
79
|
+
|
|
80
|
+
for i, v in enumerate(values, 1):
|
|
81
|
+
k = "{}_{}".format(key, i)
|
|
82
|
+
self.set(k, v)
|
|
83
|
+
|
|
84
|
+
def delete(self, key):
|
|
85
|
+
"""remove key from the environment"""
|
|
86
|
+
self.__delattr__(key)
|
|
87
|
+
#os.environ.pop(self.key(key), None)
|
|
88
|
+
|
|
89
|
+
def __delitem__(self, key):
|
|
90
|
+
#os.environ.pop(self.key(key), None)
|
|
91
|
+
self.environ.pop(self.key(key), None)
|
|
92
|
+
|
|
93
|
+
def ndelete(self, key):
|
|
94
|
+
"""remove all key_* from the environment"""
|
|
95
|
+
for k in self.nkeys(key):
|
|
96
|
+
#os.environ.pop(k)
|
|
97
|
+
self.environ.pop(k, None)
|
|
98
|
+
|
|
99
|
+
def get(self, key, default=None):
|
|
100
|
+
"""get a value for key from the environment
|
|
101
|
+
|
|
102
|
+
:param key: string, this will be normalized using the key() method
|
|
103
|
+
:returns: mixed, the value in the environment of key, or default if key
|
|
104
|
+
is not in the environment
|
|
105
|
+
"""
|
|
106
|
+
try:
|
|
107
|
+
return self[key]
|
|
108
|
+
|
|
109
|
+
except KeyError:
|
|
110
|
+
return default
|
|
111
|
+
#return os.environ.get(self.key(key), default)
|
|
112
|
+
|
|
113
|
+
def pop(self, key, *defaults):
|
|
114
|
+
try:
|
|
115
|
+
return self.__getitem__(key)
|
|
116
|
+
|
|
117
|
+
except KeyError:
|
|
118
|
+
if defaults:
|
|
119
|
+
return defaults[0]
|
|
120
|
+
|
|
121
|
+
else:
|
|
122
|
+
raise
|
|
123
|
+
|
|
124
|
+
def __getitem__(self, key):
|
|
125
|
+
ek = self.ekey(key)
|
|
126
|
+
k = self.key(key)
|
|
127
|
+
try:
|
|
128
|
+
#return os.environ[k]
|
|
129
|
+
v = self.environ[k]
|
|
130
|
+
|
|
131
|
+
except KeyError:
|
|
132
|
+
v = self.defaults[ek]["value"]
|
|
133
|
+
|
|
134
|
+
if ek in self.defaults:
|
|
135
|
+
if self.defaults[ek]["type"]:
|
|
136
|
+
v = self.defaults[ek]["type"](v)
|
|
137
|
+
|
|
138
|
+
return v
|
|
139
|
+
|
|
140
|
+
def __getattr__(self, key):
|
|
141
|
+
try:
|
|
142
|
+
return self.__getitem__(key)
|
|
143
|
+
|
|
144
|
+
except KeyError as e:
|
|
145
|
+
raise AttributeError(key) from e
|
|
146
|
+
|
|
147
|
+
def nget(self, key):
|
|
148
|
+
"""this will look for key, and key_N (where
|
|
149
|
+
N is 1 to infinity) in the environment
|
|
150
|
+
|
|
151
|
+
The number checks (eg *_1, *_2) go in order, so you can't do *_1, *_3,
|
|
152
|
+
because it will fail on missing *_2 and move on, so make sure your number
|
|
153
|
+
suffixes are in order (eg, 1, 2, 3, ...)
|
|
154
|
+
|
|
155
|
+
:param key: string, the name of the environment variables
|
|
156
|
+
:returns: generator, the found values for key and key_* variants
|
|
157
|
+
"""
|
|
158
|
+
for nkey in self.nkeys(key):
|
|
159
|
+
#yield os.environ[nkey]
|
|
160
|
+
yield self.environ[nkey]
|
|
161
|
+
|
|
162
|
+
def keys(self):
|
|
163
|
+
"""yields all the keys of the given namespace currently in the environment"""
|
|
164
|
+
for k, _ in self.items():
|
|
165
|
+
yield k
|
|
166
|
+
|
|
167
|
+
def values(self):
|
|
168
|
+
"""yields all the keys of the given namespace currently in the environment"""
|
|
169
|
+
for _, v in self.items():
|
|
170
|
+
yield v
|
|
171
|
+
|
|
172
|
+
def items(self):
|
|
173
|
+
#for k, v in os.environ.items():
|
|
174
|
+
seen = set()
|
|
175
|
+
for k, v in self.environ.items():
|
|
176
|
+
if k.startswith(self.namespace):
|
|
177
|
+
ek = self.ekey(k)
|
|
178
|
+
seen.add(ek)
|
|
179
|
+
yield ek, v
|
|
180
|
+
|
|
181
|
+
for ek, d in self.defaults.items():
|
|
182
|
+
if ek not in seen:
|
|
183
|
+
yield ek, d["value"]
|
|
184
|
+
|
|
185
|
+
def __iter__(self):
|
|
186
|
+
return self.keys()
|
|
187
|
+
|
|
188
|
+
def key(self, key):
|
|
189
|
+
"""normalizes key to have the namespace
|
|
190
|
+
|
|
191
|
+
:Example:
|
|
192
|
+
environ = Environ("FOO_")
|
|
193
|
+
k = environ.key("BAR")
|
|
194
|
+
print(k) # FOO_BAR
|
|
195
|
+
"""
|
|
196
|
+
if self.namespace and not key.startswith(self.namespace):
|
|
197
|
+
key = self.namespace + key
|
|
198
|
+
return key
|
|
199
|
+
|
|
200
|
+
def ekey(self, key):
|
|
201
|
+
"""Given a full namespaced key return the key name without the namespace
|
|
202
|
+
|
|
203
|
+
:Example:
|
|
204
|
+
environ = Environ("FOO_")
|
|
205
|
+
k = environ.ekey("FOO_BAR")
|
|
206
|
+
print(k) # BAR
|
|
207
|
+
"""
|
|
208
|
+
return key.replace(self.namespace, "")
|
|
209
|
+
|
|
210
|
+
def nkey(self, key, n):
|
|
211
|
+
"""internal method. Helper method for nkeys"""
|
|
212
|
+
k = self.key(key)
|
|
213
|
+
for fmt in ["{key}_{n}", "{key}{n}"]:
|
|
214
|
+
nkey = fmt.format(key=k, n=n)
|
|
215
|
+
if nkey in self.environ:
|
|
216
|
+
#if nkey in os.environ:
|
|
217
|
+
return nkey
|
|
218
|
+
|
|
219
|
+
raise KeyError("Environ {} has no {} key".format(key, n))
|
|
220
|
+
|
|
221
|
+
def nkeys(self, key):
|
|
222
|
+
"""This returns the actual environment variable names from * -> *_N
|
|
223
|
+
|
|
224
|
+
:param key: string, the name of the environment variables
|
|
225
|
+
:returns: generator, the found environment names
|
|
226
|
+
"""
|
|
227
|
+
k = self.key(key)
|
|
228
|
+
#if k in os.environ:
|
|
229
|
+
if k in self.environ:
|
|
230
|
+
yield k
|
|
231
|
+
|
|
232
|
+
# now try importing _1 -> _N prefixes
|
|
233
|
+
n = 0
|
|
234
|
+
while True:
|
|
235
|
+
try:
|
|
236
|
+
yield self.nkey(key, n)
|
|
237
|
+
|
|
238
|
+
except KeyError:
|
|
239
|
+
# 0 is a special case, so if it fails we keep going
|
|
240
|
+
if n:
|
|
241
|
+
# we are done because we missed an n value
|
|
242
|
+
break
|
|
243
|
+
|
|
244
|
+
finally:
|
|
245
|
+
n += 1
|
|
246
|
+
|
|
247
|
+
def paths(self, key):
|
|
248
|
+
"""splits the value at key by the path separator and yields each individual
|
|
249
|
+
path part
|
|
250
|
+
|
|
251
|
+
splits each value using the path separator
|
|
252
|
+
|
|
253
|
+
:param key: str, the key
|
|
254
|
+
:returns: generator, each part of the value found at key
|
|
255
|
+
"""
|
|
256
|
+
sep = os.pathsep
|
|
257
|
+
for paths in self.nget(key):
|
|
258
|
+
for p in paths.split(sep):
|
|
259
|
+
yield p
|
|
260
|
+
|
|
261
|
+
def has(self, key):
|
|
262
|
+
"""Return True if key is in the environment
|
|
263
|
+
|
|
264
|
+
:param k: str
|
|
265
|
+
:returns: bool
|
|
266
|
+
"""
|
|
267
|
+
#return self.key(key) in os.environ
|
|
268
|
+
return self.key(key) in self.environ
|
|
269
|
+
|
|
270
|
+
def __contains__(self, key):
|
|
271
|
+
return self.has(key)
|
|
272
|
+
|
|
273
|
+
def __len__(self):
|
|
274
|
+
return len(list(self.keys()))
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
###############################################################################
|
|
278
|
+
# Actual environment configuration that is used throughout the package
|
|
279
|
+
###############################################################################
|
|
280
|
+
environ = Environ("DATATYPES_")
|
|
281
|
+
|
|
282
|
+
environ.setdefault("ENCODING", "UTF-8")
|
|
283
|
+
"""For things that need encoding, this will be the default encoding if nothing
|
|
284
|
+
else is passed in"""
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
environ.setdefault("ENCODING_ERRORS", "replace")
|
|
288
|
+
"""For things that need encoding, this will handle any errors"""
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
# 2021-1-15 - we place our cache by default into another directory because I
|
|
292
|
+
# have problems running some commands like touch on the base temp directory on
|
|
293
|
+
# MacOS on Python3, no idea why but I couldn't get around it
|
|
294
|
+
environ.setdefault(
|
|
295
|
+
"CACHE_DIR",
|
|
296
|
+
os.path.join(tempfile.gettempdir(), environ.namespace.lower().rstrip("_"))
|
|
297
|
+
)
|
|
298
|
+
"""the default caching directory for things that need a cache folder"""
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
environ.setdefault("USER_AGENT", "")
|
|
302
|
+
|