Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitattributes +2 -0
- my_container_sandbox/workspace/anaconda3/lib/itcl4.2.2/libitclstub4.2.2.a +0 -0
- my_container_sandbox/workspace/anaconda3/lib/libnppicc.so +3 -0
- my_container_sandbox/workspace/anaconda3/lib/libnppitc.so.11 +3 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/__future__.py +147 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/_markupbase.py +395 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/_osx_support.py +575 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/_sitebuiltins.py +103 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/_strptime.py +579 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata__linux_x86_64-linux-gnu.py +692 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata__linux_x86_64-linux-gnu.py.orig +952 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata_aarch64_conda_linux_gnu.py +805 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata_i686_conda_cos6_linux_gnu.py +773 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata_s390x_conda_linux_gnu.py +773 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata_x86_64_conda_cos7_linux_gnu.py +773 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata_x86_64_conda_linux_gnu.py +773 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/antigravity.py +17 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/ast.py +547 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/asynchat.py +307 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/base64.py +595 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/bdb.py +880 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/binhex.py +479 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/cProfile.py +207 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/calendar.py +770 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/cgi.py +1001 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/cgitb.py +321 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/code.py +315 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/codecs.py +1126 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/codeop.py +178 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/crypt.py +112 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/decimal.py +11 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/dis.py +553 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/enum.py +1018 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/filecmp.py +305 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/formatter.py +452 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/functools.py +976 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/getpass.py +185 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/gettext.py +782 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/gzip.py +600 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/hashlib.py +259 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/imp.py +345 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/inspect.py +0 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/io.py +99 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/lzma.py +347 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/mailbox.py +2146 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/mimetypes.py +614 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/modulefinder.py +687 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/netrc.py +139 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/nntplib.py +1151 -0
- my_container_sandbox/workspace/anaconda3/lib/python3.8/numbers.py +389 -0
.gitattributes
CHANGED
|
@@ -148,3 +148,5 @@ my_container_sandbox/workspace/anaconda3/lib/libnppial.so filter=lfs diff=lfs me
|
|
| 148 |
my_container_sandbox/workspace/anaconda3/lib/libsqlite3.so.0.8.6 filter=lfs diff=lfs merge=lfs -text
|
| 149 |
my_container_sandbox/workspace/anaconda3/lib/libcudart.so filter=lfs diff=lfs merge=lfs -text
|
| 150 |
my_container_sandbox/workspace/anaconda3/lib/libz.so.1.2.13 filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
| 148 |
my_container_sandbox/workspace/anaconda3/lib/libsqlite3.so.0.8.6 filter=lfs diff=lfs merge=lfs -text
|
| 149 |
my_container_sandbox/workspace/anaconda3/lib/libcudart.so filter=lfs diff=lfs merge=lfs -text
|
| 150 |
my_container_sandbox/workspace/anaconda3/lib/libz.so.1.2.13 filter=lfs diff=lfs merge=lfs -text
|
| 151 |
+
my_container_sandbox/workspace/anaconda3/lib/libnppicc.so filter=lfs diff=lfs merge=lfs -text
|
| 152 |
+
my_container_sandbox/workspace/anaconda3/lib/libnppitc.so.11 filter=lfs diff=lfs merge=lfs -text
|
my_container_sandbox/workspace/anaconda3/lib/itcl4.2.2/libitclstub4.2.2.a
ADDED
|
Binary file (2.83 kB). View file
|
|
|
my_container_sandbox/workspace/anaconda3/lib/libnppicc.so
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c7c756f65b011b05e8bc1dfcd7d2856159d3dacb2e7753caa97965d862ca08b0
|
| 3 |
+
size 6357432
|
my_container_sandbox/workspace/anaconda3/lib/libnppitc.so.11
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e59c811a2478ca8f1335e787c046eabaaa9a0ac1589b898f3f5bc10b57527503
|
| 3 |
+
size 4306408
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/__future__.py
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Record of phased-in incompatible language changes.
|
| 2 |
+
|
| 3 |
+
Each line is of the form:
|
| 4 |
+
|
| 5 |
+
FeatureName = "_Feature(" OptionalRelease "," MandatoryRelease ","
|
| 6 |
+
CompilerFlag ")"
|
| 7 |
+
|
| 8 |
+
where, normally, OptionalRelease < MandatoryRelease, and both are 5-tuples
|
| 9 |
+
of the same form as sys.version_info:
|
| 10 |
+
|
| 11 |
+
(PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int
|
| 12 |
+
PY_MINOR_VERSION, # the 1; an int
|
| 13 |
+
PY_MICRO_VERSION, # the 0; an int
|
| 14 |
+
PY_RELEASE_LEVEL, # "alpha", "beta", "candidate" or "final"; string
|
| 15 |
+
PY_RELEASE_SERIAL # the 3; an int
|
| 16 |
+
)
|
| 17 |
+
|
| 18 |
+
OptionalRelease records the first release in which
|
| 19 |
+
|
| 20 |
+
from __future__ import FeatureName
|
| 21 |
+
|
| 22 |
+
was accepted.
|
| 23 |
+
|
| 24 |
+
In the case of MandatoryReleases that have not yet occurred,
|
| 25 |
+
MandatoryRelease predicts the release in which the feature will become part
|
| 26 |
+
of the language.
|
| 27 |
+
|
| 28 |
+
Else MandatoryRelease records when the feature became part of the language;
|
| 29 |
+
in releases at or after that, modules no longer need
|
| 30 |
+
|
| 31 |
+
from __future__ import FeatureName
|
| 32 |
+
|
| 33 |
+
to use the feature in question, but may continue to use such imports.
|
| 34 |
+
|
| 35 |
+
MandatoryRelease may also be None, meaning that a planned feature got
|
| 36 |
+
dropped.
|
| 37 |
+
|
| 38 |
+
Instances of class _Feature have two corresponding methods,
|
| 39 |
+
.getOptionalRelease() and .getMandatoryRelease().
|
| 40 |
+
|
| 41 |
+
CompilerFlag is the (bitfield) flag that should be passed in the fourth
|
| 42 |
+
argument to the builtin function compile() to enable the feature in
|
| 43 |
+
dynamically compiled code. This flag is stored in the .compiler_flag
|
| 44 |
+
attribute on _Future instances. These values must match the appropriate
|
| 45 |
+
#defines of CO_xxx flags in Include/compile.h.
|
| 46 |
+
|
| 47 |
+
No feature line is ever to be deleted from this file.
|
| 48 |
+
"""
|
| 49 |
+
|
| 50 |
+
all_feature_names = [
|
| 51 |
+
"nested_scopes",
|
| 52 |
+
"generators",
|
| 53 |
+
"division",
|
| 54 |
+
"absolute_import",
|
| 55 |
+
"with_statement",
|
| 56 |
+
"print_function",
|
| 57 |
+
"unicode_literals",
|
| 58 |
+
"barry_as_FLUFL",
|
| 59 |
+
"generator_stop",
|
| 60 |
+
"annotations",
|
| 61 |
+
]
|
| 62 |
+
|
| 63 |
+
__all__ = ["all_feature_names"] + all_feature_names
|
| 64 |
+
|
| 65 |
+
# The CO_xxx symbols are defined here under the same names defined in
|
| 66 |
+
# code.h and used by compile.h, so that an editor search will find them here.
|
| 67 |
+
# However, they're not exported in __all__, because they don't really belong to
|
| 68 |
+
# this module.
|
| 69 |
+
CO_NESTED = 0x0010 # nested_scopes
|
| 70 |
+
CO_GENERATOR_ALLOWED = 0 # generators (obsolete, was 0x1000)
|
| 71 |
+
CO_FUTURE_DIVISION = 0x20000 # division
|
| 72 |
+
CO_FUTURE_ABSOLUTE_IMPORT = 0x40000 # perform absolute imports by default
|
| 73 |
+
CO_FUTURE_WITH_STATEMENT = 0x80000 # with statement
|
| 74 |
+
CO_FUTURE_PRINT_FUNCTION = 0x100000 # print function
|
| 75 |
+
CO_FUTURE_UNICODE_LITERALS = 0x200000 # unicode string literals
|
| 76 |
+
CO_FUTURE_BARRY_AS_BDFL = 0x400000
|
| 77 |
+
CO_FUTURE_GENERATOR_STOP = 0x800000 # StopIteration becomes RuntimeError in generators
|
| 78 |
+
CO_FUTURE_ANNOTATIONS = 0x1000000 # annotations become strings at runtime
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
class _Feature:
|
| 82 |
+
|
| 83 |
+
def __init__(self, optionalRelease, mandatoryRelease, compiler_flag):
|
| 84 |
+
self.optional = optionalRelease
|
| 85 |
+
self.mandatory = mandatoryRelease
|
| 86 |
+
self.compiler_flag = compiler_flag
|
| 87 |
+
|
| 88 |
+
def getOptionalRelease(self):
|
| 89 |
+
"""Return first release in which this feature was recognized.
|
| 90 |
+
|
| 91 |
+
This is a 5-tuple, of the same form as sys.version_info.
|
| 92 |
+
"""
|
| 93 |
+
return self.optional
|
| 94 |
+
|
| 95 |
+
def getMandatoryRelease(self):
|
| 96 |
+
"""Return release in which this feature will become mandatory.
|
| 97 |
+
|
| 98 |
+
This is a 5-tuple, of the same form as sys.version_info, or, if
|
| 99 |
+
the feature was dropped, is None.
|
| 100 |
+
"""
|
| 101 |
+
return self.mandatory
|
| 102 |
+
|
| 103 |
+
def __repr__(self):
|
| 104 |
+
return "_Feature" + repr((self.optional,
|
| 105 |
+
self.mandatory,
|
| 106 |
+
self.compiler_flag))
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
nested_scopes = _Feature((2, 1, 0, "beta", 1),
|
| 110 |
+
(2, 2, 0, "alpha", 0),
|
| 111 |
+
CO_NESTED)
|
| 112 |
+
|
| 113 |
+
generators = _Feature((2, 2, 0, "alpha", 1),
|
| 114 |
+
(2, 3, 0, "final", 0),
|
| 115 |
+
CO_GENERATOR_ALLOWED)
|
| 116 |
+
|
| 117 |
+
division = _Feature((2, 2, 0, "alpha", 2),
|
| 118 |
+
(3, 0, 0, "alpha", 0),
|
| 119 |
+
CO_FUTURE_DIVISION)
|
| 120 |
+
|
| 121 |
+
absolute_import = _Feature((2, 5, 0, "alpha", 1),
|
| 122 |
+
(3, 0, 0, "alpha", 0),
|
| 123 |
+
CO_FUTURE_ABSOLUTE_IMPORT)
|
| 124 |
+
|
| 125 |
+
with_statement = _Feature((2, 5, 0, "alpha", 1),
|
| 126 |
+
(2, 6, 0, "alpha", 0),
|
| 127 |
+
CO_FUTURE_WITH_STATEMENT)
|
| 128 |
+
|
| 129 |
+
print_function = _Feature((2, 6, 0, "alpha", 2),
|
| 130 |
+
(3, 0, 0, "alpha", 0),
|
| 131 |
+
CO_FUTURE_PRINT_FUNCTION)
|
| 132 |
+
|
| 133 |
+
unicode_literals = _Feature((2, 6, 0, "alpha", 2),
|
| 134 |
+
(3, 0, 0, "alpha", 0),
|
| 135 |
+
CO_FUTURE_UNICODE_LITERALS)
|
| 136 |
+
|
| 137 |
+
barry_as_FLUFL = _Feature((3, 1, 0, "alpha", 2),
|
| 138 |
+
(4, 0, 0, "alpha", 0),
|
| 139 |
+
CO_FUTURE_BARRY_AS_BDFL)
|
| 140 |
+
|
| 141 |
+
generator_stop = _Feature((3, 5, 0, "beta", 1),
|
| 142 |
+
(3, 7, 0, "alpha", 0),
|
| 143 |
+
CO_FUTURE_GENERATOR_STOP)
|
| 144 |
+
|
| 145 |
+
annotations = _Feature((3, 7, 0, "beta", 1),
|
| 146 |
+
(3, 10, 0, "alpha", 0),
|
| 147 |
+
CO_FUTURE_ANNOTATIONS)
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/_markupbase.py
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Shared support for scanning document type declarations in HTML and XHTML.
|
| 2 |
+
|
| 3 |
+
This module is used as a foundation for the html.parser module. It has no
|
| 4 |
+
documented public API and should not be used directly.
|
| 5 |
+
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
import re
|
| 9 |
+
|
| 10 |
+
_declname_match = re.compile(r'[a-zA-Z][-_.a-zA-Z0-9]*\s*').match
|
| 11 |
+
_declstringlit_match = re.compile(r'(\'[^\']*\'|"[^"]*")\s*').match
|
| 12 |
+
_commentclose = re.compile(r'--\s*>')
|
| 13 |
+
_markedsectionclose = re.compile(r']\s*]\s*>')
|
| 14 |
+
|
| 15 |
+
# An analysis of the MS-Word extensions is available at
|
| 16 |
+
# http://www.planetpublish.com/xmlarena/xap/Thursday/WordtoXML.pdf
|
| 17 |
+
|
| 18 |
+
_msmarkedsectionclose = re.compile(r']\s*>')
|
| 19 |
+
|
| 20 |
+
del re
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
class ParserBase:
|
| 24 |
+
"""Parser base class which provides some common support methods used
|
| 25 |
+
by the SGML/HTML and XHTML parsers."""
|
| 26 |
+
|
| 27 |
+
def __init__(self):
|
| 28 |
+
if self.__class__ is ParserBase:
|
| 29 |
+
raise RuntimeError(
|
| 30 |
+
"_markupbase.ParserBase must be subclassed")
|
| 31 |
+
|
| 32 |
+
def error(self, message):
|
| 33 |
+
raise NotImplementedError(
|
| 34 |
+
"subclasses of ParserBase must override error()")
|
| 35 |
+
|
| 36 |
+
def reset(self):
|
| 37 |
+
self.lineno = 1
|
| 38 |
+
self.offset = 0
|
| 39 |
+
|
| 40 |
+
def getpos(self):
|
| 41 |
+
"""Return current line number and offset."""
|
| 42 |
+
return self.lineno, self.offset
|
| 43 |
+
|
| 44 |
+
# Internal -- update line number and offset. This should be
|
| 45 |
+
# called for each piece of data exactly once, in order -- in other
|
| 46 |
+
# words the concatenation of all the input strings to this
|
| 47 |
+
# function should be exactly the entire input.
|
| 48 |
+
def updatepos(self, i, j):
|
| 49 |
+
if i >= j:
|
| 50 |
+
return j
|
| 51 |
+
rawdata = self.rawdata
|
| 52 |
+
nlines = rawdata.count("\n", i, j)
|
| 53 |
+
if nlines:
|
| 54 |
+
self.lineno = self.lineno + nlines
|
| 55 |
+
pos = rawdata.rindex("\n", i, j) # Should not fail
|
| 56 |
+
self.offset = j-(pos+1)
|
| 57 |
+
else:
|
| 58 |
+
self.offset = self.offset + j-i
|
| 59 |
+
return j
|
| 60 |
+
|
| 61 |
+
_decl_otherchars = ''
|
| 62 |
+
|
| 63 |
+
# Internal -- parse declaration (for use by subclasses).
|
| 64 |
+
def parse_declaration(self, i):
|
| 65 |
+
# This is some sort of declaration; in "HTML as
|
| 66 |
+
# deployed," this should only be the document type
|
| 67 |
+
# declaration ("<!DOCTYPE html...>").
|
| 68 |
+
# ISO 8879:1986, however, has more complex
|
| 69 |
+
# declaration syntax for elements in <!...>, including:
|
| 70 |
+
# --comment--
|
| 71 |
+
# [marked section]
|
| 72 |
+
# name in the following list: ENTITY, DOCTYPE, ELEMENT,
|
| 73 |
+
# ATTLIST, NOTATION, SHORTREF, USEMAP,
|
| 74 |
+
# LINKTYPE, LINK, IDLINK, USELINK, SYSTEM
|
| 75 |
+
rawdata = self.rawdata
|
| 76 |
+
j = i + 2
|
| 77 |
+
assert rawdata[i:j] == "<!", "unexpected call to parse_declaration"
|
| 78 |
+
if rawdata[j:j+1] == ">":
|
| 79 |
+
# the empty comment <!>
|
| 80 |
+
return j + 1
|
| 81 |
+
if rawdata[j:j+1] in ("-", ""):
|
| 82 |
+
# Start of comment followed by buffer boundary,
|
| 83 |
+
# or just a buffer boundary.
|
| 84 |
+
return -1
|
| 85 |
+
# A simple, practical version could look like: ((name|stringlit) S*) + '>'
|
| 86 |
+
n = len(rawdata)
|
| 87 |
+
if rawdata[j:j+2] == '--': #comment
|
| 88 |
+
# Locate --.*-- as the body of the comment
|
| 89 |
+
return self.parse_comment(i)
|
| 90 |
+
elif rawdata[j] == '[': #marked section
|
| 91 |
+
# Locate [statusWord [...arbitrary SGML...]] as the body of the marked section
|
| 92 |
+
# Where statusWord is one of TEMP, CDATA, IGNORE, INCLUDE, RCDATA
|
| 93 |
+
# Note that this is extended by Microsoft Office "Save as Web" function
|
| 94 |
+
# to include [if...] and [endif].
|
| 95 |
+
return self.parse_marked_section(i)
|
| 96 |
+
else: #all other declaration elements
|
| 97 |
+
decltype, j = self._scan_name(j, i)
|
| 98 |
+
if j < 0:
|
| 99 |
+
return j
|
| 100 |
+
if decltype == "doctype":
|
| 101 |
+
self._decl_otherchars = ''
|
| 102 |
+
while j < n:
|
| 103 |
+
c = rawdata[j]
|
| 104 |
+
if c == ">":
|
| 105 |
+
# end of declaration syntax
|
| 106 |
+
data = rawdata[i+2:j]
|
| 107 |
+
if decltype == "doctype":
|
| 108 |
+
self.handle_decl(data)
|
| 109 |
+
else:
|
| 110 |
+
# According to the HTML5 specs sections "8.2.4.44 Bogus
|
| 111 |
+
# comment state" and "8.2.4.45 Markup declaration open
|
| 112 |
+
# state", a comment token should be emitted.
|
| 113 |
+
# Calling unknown_decl provides more flexibility though.
|
| 114 |
+
self.unknown_decl(data)
|
| 115 |
+
return j + 1
|
| 116 |
+
if c in "\"'":
|
| 117 |
+
m = _declstringlit_match(rawdata, j)
|
| 118 |
+
if not m:
|
| 119 |
+
return -1 # incomplete
|
| 120 |
+
j = m.end()
|
| 121 |
+
elif c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ":
|
| 122 |
+
name, j = self._scan_name(j, i)
|
| 123 |
+
elif c in self._decl_otherchars:
|
| 124 |
+
j = j + 1
|
| 125 |
+
elif c == "[":
|
| 126 |
+
# this could be handled in a separate doctype parser
|
| 127 |
+
if decltype == "doctype":
|
| 128 |
+
j = self._parse_doctype_subset(j + 1, i)
|
| 129 |
+
elif decltype in {"attlist", "linktype", "link", "element"}:
|
| 130 |
+
# must tolerate []'d groups in a content model in an element declaration
|
| 131 |
+
# also in data attribute specifications of attlist declaration
|
| 132 |
+
# also link type declaration subsets in linktype declarations
|
| 133 |
+
# also link attribute specification lists in link declarations
|
| 134 |
+
self.error("unsupported '[' char in %s declaration" % decltype)
|
| 135 |
+
else:
|
| 136 |
+
self.error("unexpected '[' char in declaration")
|
| 137 |
+
else:
|
| 138 |
+
self.error(
|
| 139 |
+
"unexpected %r char in declaration" % rawdata[j])
|
| 140 |
+
if j < 0:
|
| 141 |
+
return j
|
| 142 |
+
return -1 # incomplete
|
| 143 |
+
|
| 144 |
+
# Internal -- parse a marked section
|
| 145 |
+
# Override this to handle MS-word extension syntax <![if word]>content<![endif]>
|
| 146 |
+
def parse_marked_section(self, i, report=1):
|
| 147 |
+
rawdata= self.rawdata
|
| 148 |
+
assert rawdata[i:i+3] == '<![', "unexpected call to parse_marked_section()"
|
| 149 |
+
sectName, j = self._scan_name( i+3, i )
|
| 150 |
+
if j < 0:
|
| 151 |
+
return j
|
| 152 |
+
if sectName in {"temp", "cdata", "ignore", "include", "rcdata"}:
|
| 153 |
+
# look for standard ]]> ending
|
| 154 |
+
match= _markedsectionclose.search(rawdata, i+3)
|
| 155 |
+
elif sectName in {"if", "else", "endif"}:
|
| 156 |
+
# look for MS Office ]> ending
|
| 157 |
+
match= _msmarkedsectionclose.search(rawdata, i+3)
|
| 158 |
+
else:
|
| 159 |
+
self.error('unknown status keyword %r in marked section' % rawdata[i+3:j])
|
| 160 |
+
if not match:
|
| 161 |
+
return -1
|
| 162 |
+
if report:
|
| 163 |
+
j = match.start(0)
|
| 164 |
+
self.unknown_decl(rawdata[i+3: j])
|
| 165 |
+
return match.end(0)
|
| 166 |
+
|
| 167 |
+
# Internal -- parse comment, return length or -1 if not terminated
|
| 168 |
+
def parse_comment(self, i, report=1):
|
| 169 |
+
rawdata = self.rawdata
|
| 170 |
+
if rawdata[i:i+4] != '<!--':
|
| 171 |
+
self.error('unexpected call to parse_comment()')
|
| 172 |
+
match = _commentclose.search(rawdata, i+4)
|
| 173 |
+
if not match:
|
| 174 |
+
return -1
|
| 175 |
+
if report:
|
| 176 |
+
j = match.start(0)
|
| 177 |
+
self.handle_comment(rawdata[i+4: j])
|
| 178 |
+
return match.end(0)
|
| 179 |
+
|
| 180 |
+
# Internal -- scan past the internal subset in a <!DOCTYPE declaration,
|
| 181 |
+
# returning the index just past any whitespace following the trailing ']'.
|
| 182 |
+
def _parse_doctype_subset(self, i, declstartpos):
|
| 183 |
+
rawdata = self.rawdata
|
| 184 |
+
n = len(rawdata)
|
| 185 |
+
j = i
|
| 186 |
+
while j < n:
|
| 187 |
+
c = rawdata[j]
|
| 188 |
+
if c == "<":
|
| 189 |
+
s = rawdata[j:j+2]
|
| 190 |
+
if s == "<":
|
| 191 |
+
# end of buffer; incomplete
|
| 192 |
+
return -1
|
| 193 |
+
if s != "<!":
|
| 194 |
+
self.updatepos(declstartpos, j + 1)
|
| 195 |
+
self.error("unexpected char in internal subset (in %r)" % s)
|
| 196 |
+
if (j + 2) == n:
|
| 197 |
+
# end of buffer; incomplete
|
| 198 |
+
return -1
|
| 199 |
+
if (j + 4) > n:
|
| 200 |
+
# end of buffer; incomplete
|
| 201 |
+
return -1
|
| 202 |
+
if rawdata[j:j+4] == "<!--":
|
| 203 |
+
j = self.parse_comment(j, report=0)
|
| 204 |
+
if j < 0:
|
| 205 |
+
return j
|
| 206 |
+
continue
|
| 207 |
+
name, j = self._scan_name(j + 2, declstartpos)
|
| 208 |
+
if j == -1:
|
| 209 |
+
return -1
|
| 210 |
+
if name not in {"attlist", "element", "entity", "notation"}:
|
| 211 |
+
self.updatepos(declstartpos, j + 2)
|
| 212 |
+
self.error(
|
| 213 |
+
"unknown declaration %r in internal subset" % name)
|
| 214 |
+
# handle the individual names
|
| 215 |
+
meth = getattr(self, "_parse_doctype_" + name)
|
| 216 |
+
j = meth(j, declstartpos)
|
| 217 |
+
if j < 0:
|
| 218 |
+
return j
|
| 219 |
+
elif c == "%":
|
| 220 |
+
# parameter entity reference
|
| 221 |
+
if (j + 1) == n:
|
| 222 |
+
# end of buffer; incomplete
|
| 223 |
+
return -1
|
| 224 |
+
s, j = self._scan_name(j + 1, declstartpos)
|
| 225 |
+
if j < 0:
|
| 226 |
+
return j
|
| 227 |
+
if rawdata[j] == ";":
|
| 228 |
+
j = j + 1
|
| 229 |
+
elif c == "]":
|
| 230 |
+
j = j + 1
|
| 231 |
+
while j < n and rawdata[j].isspace():
|
| 232 |
+
j = j + 1
|
| 233 |
+
if j < n:
|
| 234 |
+
if rawdata[j] == ">":
|
| 235 |
+
return j
|
| 236 |
+
self.updatepos(declstartpos, j)
|
| 237 |
+
self.error("unexpected char after internal subset")
|
| 238 |
+
else:
|
| 239 |
+
return -1
|
| 240 |
+
elif c.isspace():
|
| 241 |
+
j = j + 1
|
| 242 |
+
else:
|
| 243 |
+
self.updatepos(declstartpos, j)
|
| 244 |
+
self.error("unexpected char %r in internal subset" % c)
|
| 245 |
+
# end of buffer reached
|
| 246 |
+
return -1
|
| 247 |
+
|
| 248 |
+
# Internal -- scan past <!ELEMENT declarations
|
| 249 |
+
def _parse_doctype_element(self, i, declstartpos):
|
| 250 |
+
name, j = self._scan_name(i, declstartpos)
|
| 251 |
+
if j == -1:
|
| 252 |
+
return -1
|
| 253 |
+
# style content model; just skip until '>'
|
| 254 |
+
rawdata = self.rawdata
|
| 255 |
+
if '>' in rawdata[j:]:
|
| 256 |
+
return rawdata.find(">", j) + 1
|
| 257 |
+
return -1
|
| 258 |
+
|
| 259 |
+
# Internal -- scan past <!ATTLIST declarations
|
| 260 |
+
def _parse_doctype_attlist(self, i, declstartpos):
|
| 261 |
+
rawdata = self.rawdata
|
| 262 |
+
name, j = self._scan_name(i, declstartpos)
|
| 263 |
+
c = rawdata[j:j+1]
|
| 264 |
+
if c == "":
|
| 265 |
+
return -1
|
| 266 |
+
if c == ">":
|
| 267 |
+
return j + 1
|
| 268 |
+
while 1:
|
| 269 |
+
# scan a series of attribute descriptions; simplified:
|
| 270 |
+
# name type [value] [#constraint]
|
| 271 |
+
name, j = self._scan_name(j, declstartpos)
|
| 272 |
+
if j < 0:
|
| 273 |
+
return j
|
| 274 |
+
c = rawdata[j:j+1]
|
| 275 |
+
if c == "":
|
| 276 |
+
return -1
|
| 277 |
+
if c == "(":
|
| 278 |
+
# an enumerated type; look for ')'
|
| 279 |
+
if ")" in rawdata[j:]:
|
| 280 |
+
j = rawdata.find(")", j) + 1
|
| 281 |
+
else:
|
| 282 |
+
return -1
|
| 283 |
+
while rawdata[j:j+1].isspace():
|
| 284 |
+
j = j + 1
|
| 285 |
+
if not rawdata[j:]:
|
| 286 |
+
# end of buffer, incomplete
|
| 287 |
+
return -1
|
| 288 |
+
else:
|
| 289 |
+
name, j = self._scan_name(j, declstartpos)
|
| 290 |
+
c = rawdata[j:j+1]
|
| 291 |
+
if not c:
|
| 292 |
+
return -1
|
| 293 |
+
if c in "'\"":
|
| 294 |
+
m = _declstringlit_match(rawdata, j)
|
| 295 |
+
if m:
|
| 296 |
+
j = m.end()
|
| 297 |
+
else:
|
| 298 |
+
return -1
|
| 299 |
+
c = rawdata[j:j+1]
|
| 300 |
+
if not c:
|
| 301 |
+
return -1
|
| 302 |
+
if c == "#":
|
| 303 |
+
if rawdata[j:] == "#":
|
| 304 |
+
# end of buffer
|
| 305 |
+
return -1
|
| 306 |
+
name, j = self._scan_name(j + 1, declstartpos)
|
| 307 |
+
if j < 0:
|
| 308 |
+
return j
|
| 309 |
+
c = rawdata[j:j+1]
|
| 310 |
+
if not c:
|
| 311 |
+
return -1
|
| 312 |
+
if c == '>':
|
| 313 |
+
# all done
|
| 314 |
+
return j + 1
|
| 315 |
+
|
| 316 |
+
# Internal -- scan past <!NOTATION declarations
|
| 317 |
+
def _parse_doctype_notation(self, i, declstartpos):
|
| 318 |
+
name, j = self._scan_name(i, declstartpos)
|
| 319 |
+
if j < 0:
|
| 320 |
+
return j
|
| 321 |
+
rawdata = self.rawdata
|
| 322 |
+
while 1:
|
| 323 |
+
c = rawdata[j:j+1]
|
| 324 |
+
if not c:
|
| 325 |
+
# end of buffer; incomplete
|
| 326 |
+
return -1
|
| 327 |
+
if c == '>':
|
| 328 |
+
return j + 1
|
| 329 |
+
if c in "'\"":
|
| 330 |
+
m = _declstringlit_match(rawdata, j)
|
| 331 |
+
if not m:
|
| 332 |
+
return -1
|
| 333 |
+
j = m.end()
|
| 334 |
+
else:
|
| 335 |
+
name, j = self._scan_name(j, declstartpos)
|
| 336 |
+
if j < 0:
|
| 337 |
+
return j
|
| 338 |
+
|
| 339 |
+
# Internal -- scan past <!ENTITY declarations
|
| 340 |
+
def _parse_doctype_entity(self, i, declstartpos):
|
| 341 |
+
rawdata = self.rawdata
|
| 342 |
+
if rawdata[i:i+1] == "%":
|
| 343 |
+
j = i + 1
|
| 344 |
+
while 1:
|
| 345 |
+
c = rawdata[j:j+1]
|
| 346 |
+
if not c:
|
| 347 |
+
return -1
|
| 348 |
+
if c.isspace():
|
| 349 |
+
j = j + 1
|
| 350 |
+
else:
|
| 351 |
+
break
|
| 352 |
+
else:
|
| 353 |
+
j = i
|
| 354 |
+
name, j = self._scan_name(j, declstartpos)
|
| 355 |
+
if j < 0:
|
| 356 |
+
return j
|
| 357 |
+
while 1:
|
| 358 |
+
c = self.rawdata[j:j+1]
|
| 359 |
+
if not c:
|
| 360 |
+
return -1
|
| 361 |
+
if c in "'\"":
|
| 362 |
+
m = _declstringlit_match(rawdata, j)
|
| 363 |
+
if m:
|
| 364 |
+
j = m.end()
|
| 365 |
+
else:
|
| 366 |
+
return -1 # incomplete
|
| 367 |
+
elif c == ">":
|
| 368 |
+
return j + 1
|
| 369 |
+
else:
|
| 370 |
+
name, j = self._scan_name(j, declstartpos)
|
| 371 |
+
if j < 0:
|
| 372 |
+
return j
|
| 373 |
+
|
| 374 |
+
# Internal -- scan a name token and the new position and the token, or
|
| 375 |
+
# return -1 if we've reached the end of the buffer.
|
| 376 |
+
def _scan_name(self, i, declstartpos):
|
| 377 |
+
rawdata = self.rawdata
|
| 378 |
+
n = len(rawdata)
|
| 379 |
+
if i == n:
|
| 380 |
+
return None, -1
|
| 381 |
+
m = _declname_match(rawdata, i)
|
| 382 |
+
if m:
|
| 383 |
+
s = m.group()
|
| 384 |
+
name = s.strip()
|
| 385 |
+
if (i + len(s)) == n:
|
| 386 |
+
return None, -1 # end of buffer
|
| 387 |
+
return name.lower(), m.end()
|
| 388 |
+
else:
|
| 389 |
+
self.updatepos(declstartpos, i)
|
| 390 |
+
self.error("expected name token at %r"
|
| 391 |
+
% rawdata[declstartpos:declstartpos+20])
|
| 392 |
+
|
| 393 |
+
# To be overridden -- handlers for unknown objects
|
| 394 |
+
def unknown_decl(self, data):
|
| 395 |
+
pass
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/_osx_support.py
ADDED
|
@@ -0,0 +1,575 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Shared OS X support functions."""
|
| 2 |
+
|
| 3 |
+
import os
|
| 4 |
+
import re
|
| 5 |
+
import sys
|
| 6 |
+
|
| 7 |
+
__all__ = [
|
| 8 |
+
'compiler_fixup',
|
| 9 |
+
'customize_config_vars',
|
| 10 |
+
'customize_compiler',
|
| 11 |
+
'get_platform_osx',
|
| 12 |
+
]
|
| 13 |
+
|
| 14 |
+
# configuration variables that may contain universal build flags,
|
| 15 |
+
# like "-arch" or "-isdkroot", that may need customization for
|
| 16 |
+
# the user environment
|
| 17 |
+
_UNIVERSAL_CONFIG_VARS = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS', 'BASECFLAGS',
|
| 18 |
+
'BLDSHARED', 'LDSHARED', 'CC', 'CXX',
|
| 19 |
+
'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
|
| 20 |
+
'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS')
|
| 21 |
+
|
| 22 |
+
# configuration variables that may contain compiler calls
|
| 23 |
+
_COMPILER_CONFIG_VARS = ('BLDSHARED', 'LDSHARED', 'CC', 'CXX')
|
| 24 |
+
|
| 25 |
+
# prefix added to original configuration variable names
|
| 26 |
+
_INITPRE = '_OSX_SUPPORT_INITIAL_'
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def _find_executable(executable, path=None):
|
| 30 |
+
"""Tries to find 'executable' in the directories listed in 'path'.
|
| 31 |
+
|
| 32 |
+
A string listing directories separated by 'os.pathsep'; defaults to
|
| 33 |
+
os.environ['PATH']. Returns the complete filename or None if not found.
|
| 34 |
+
"""
|
| 35 |
+
if path is None:
|
| 36 |
+
path = os.environ['PATH']
|
| 37 |
+
|
| 38 |
+
paths = path.split(os.pathsep)
|
| 39 |
+
base, ext = os.path.splitext(executable)
|
| 40 |
+
|
| 41 |
+
if (sys.platform == 'win32') and (ext != '.exe'):
|
| 42 |
+
executable = executable + '.exe'
|
| 43 |
+
|
| 44 |
+
if not os.path.isfile(executable):
|
| 45 |
+
for p in paths:
|
| 46 |
+
f = os.path.join(p, executable)
|
| 47 |
+
if os.path.isfile(f):
|
| 48 |
+
# the file exists, we have a shot at spawn working
|
| 49 |
+
return f
|
| 50 |
+
return None
|
| 51 |
+
else:
|
| 52 |
+
return executable
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def _read_output(commandstring, capture_stderr=False):
|
| 56 |
+
"""Output from successful command execution or None"""
|
| 57 |
+
# Similar to os.popen(commandstring, "r").read(),
|
| 58 |
+
# but without actually using os.popen because that
|
| 59 |
+
# function is not usable during python bootstrap.
|
| 60 |
+
# tempfile is also not available then.
|
| 61 |
+
import contextlib
|
| 62 |
+
try:
|
| 63 |
+
import tempfile
|
| 64 |
+
fp = tempfile.NamedTemporaryFile()
|
| 65 |
+
except ImportError:
|
| 66 |
+
fp = open("/tmp/_osx_support.%s"%(
|
| 67 |
+
os.getpid(),), "w+b")
|
| 68 |
+
|
| 69 |
+
with contextlib.closing(fp) as fp:
|
| 70 |
+
if capture_stderr:
|
| 71 |
+
cmd = "%s >'%s' 2>&1" % (commandstring, fp.name)
|
| 72 |
+
else:
|
| 73 |
+
cmd = "%s 2>/dev/null >'%s'" % (commandstring, fp.name)
|
| 74 |
+
return fp.read().decode('utf-8').strip() if not os.system(cmd) else None
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def _find_build_tool(toolname):
|
| 78 |
+
"""Find a build tool on current path or using xcrun"""
|
| 79 |
+
return (_find_executable(toolname)
|
| 80 |
+
or _read_output("/usr/bin/xcrun -find %s" % (toolname,))
|
| 81 |
+
or ''
|
| 82 |
+
)
|
| 83 |
+
|
| 84 |
+
_SYSTEM_VERSION = None
|
| 85 |
+
|
| 86 |
+
def _get_system_version():
|
| 87 |
+
"""Return the OS X system version as a string"""
|
| 88 |
+
# Reading this plist is a documented way to get the system
|
| 89 |
+
# version (see the documentation for the Gestalt Manager)
|
| 90 |
+
# We avoid using platform.mac_ver to avoid possible bootstrap issues during
|
| 91 |
+
# the build of Python itself (distutils is used to build standard library
|
| 92 |
+
# extensions).
|
| 93 |
+
|
| 94 |
+
global _SYSTEM_VERSION
|
| 95 |
+
|
| 96 |
+
if _SYSTEM_VERSION is None:
|
| 97 |
+
_SYSTEM_VERSION = ''
|
| 98 |
+
try:
|
| 99 |
+
f = open('/System/Library/CoreServices/SystemVersion.plist')
|
| 100 |
+
except OSError:
|
| 101 |
+
# We're on a plain darwin box, fall back to the default
|
| 102 |
+
# behaviour.
|
| 103 |
+
pass
|
| 104 |
+
else:
|
| 105 |
+
try:
|
| 106 |
+
m = re.search(r'<key>ProductUserVisibleVersion</key>\s*'
|
| 107 |
+
r'<string>(.*?)</string>', f.read())
|
| 108 |
+
finally:
|
| 109 |
+
f.close()
|
| 110 |
+
if m is not None:
|
| 111 |
+
_SYSTEM_VERSION = '.'.join(m.group(1).split('.')[:2])
|
| 112 |
+
# else: fall back to the default behaviour
|
| 113 |
+
|
| 114 |
+
return _SYSTEM_VERSION
|
| 115 |
+
|
| 116 |
+
_SYSTEM_VERSION_TUPLE = None
|
| 117 |
+
def _get_system_version_tuple():
|
| 118 |
+
"""
|
| 119 |
+
Return the macOS system version as a tuple
|
| 120 |
+
|
| 121 |
+
The return value is safe to use to compare
|
| 122 |
+
two version numbers.
|
| 123 |
+
"""
|
| 124 |
+
global _SYSTEM_VERSION_TUPLE
|
| 125 |
+
if _SYSTEM_VERSION_TUPLE is None:
|
| 126 |
+
osx_version = _get_system_version()
|
| 127 |
+
if osx_version:
|
| 128 |
+
try:
|
| 129 |
+
_SYSTEM_VERSION_TUPLE = tuple(int(i) for i in osx_version.split('.'))
|
| 130 |
+
except ValueError:
|
| 131 |
+
_SYSTEM_VERSION_TUPLE = ()
|
| 132 |
+
|
| 133 |
+
return _SYSTEM_VERSION_TUPLE
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
def _remove_original_values(_config_vars):
|
| 137 |
+
"""Remove original unmodified values for testing"""
|
| 138 |
+
# This is needed for higher-level cross-platform tests of get_platform.
|
| 139 |
+
for k in list(_config_vars):
|
| 140 |
+
if k.startswith(_INITPRE):
|
| 141 |
+
del _config_vars[k]
|
| 142 |
+
|
| 143 |
+
def _save_modified_value(_config_vars, cv, newvalue):
|
| 144 |
+
"""Save modified and original unmodified value of configuration var"""
|
| 145 |
+
|
| 146 |
+
oldvalue = _config_vars.get(cv, '')
|
| 147 |
+
if (oldvalue != newvalue) and (_INITPRE + cv not in _config_vars):
|
| 148 |
+
_config_vars[_INITPRE + cv] = oldvalue
|
| 149 |
+
_config_vars[cv] = newvalue
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
_cache_default_sysroot = None
|
| 153 |
+
def _default_sysroot(cc):
|
| 154 |
+
""" Returns the root of the default SDK for this system, or '/' """
|
| 155 |
+
global _cache_default_sysroot
|
| 156 |
+
|
| 157 |
+
if _cache_default_sysroot is not None:
|
| 158 |
+
return _cache_default_sysroot
|
| 159 |
+
|
| 160 |
+
contents = _read_output('%s -c -E -v - </dev/null' % (cc,), True)
|
| 161 |
+
in_incdirs = False
|
| 162 |
+
for line in contents.splitlines():
|
| 163 |
+
if line.startswith("#include <...>"):
|
| 164 |
+
in_incdirs = True
|
| 165 |
+
elif line.startswith("End of search list"):
|
| 166 |
+
in_incdirs = False
|
| 167 |
+
elif in_incdirs:
|
| 168 |
+
line = line.strip()
|
| 169 |
+
if line == '/usr/include':
|
| 170 |
+
_cache_default_sysroot = '/'
|
| 171 |
+
elif line.endswith(".sdk/usr/include"):
|
| 172 |
+
_cache_default_sysroot = line[:-12]
|
| 173 |
+
if _cache_default_sysroot is None:
|
| 174 |
+
_cache_default_sysroot = '/'
|
| 175 |
+
|
| 176 |
+
return _cache_default_sysroot
|
| 177 |
+
|
| 178 |
+
def _supports_universal_builds():
|
| 179 |
+
"""Returns True if universal builds are supported on this system"""
|
| 180 |
+
# As an approximation, we assume that if we are running on 10.4 or above,
|
| 181 |
+
# then we are running with an Xcode environment that supports universal
|
| 182 |
+
# builds, in particular -isysroot and -arch arguments to the compiler. This
|
| 183 |
+
# is in support of allowing 10.4 universal builds to run on 10.3.x systems.
|
| 184 |
+
|
| 185 |
+
osx_version = _get_system_version_tuple()
|
| 186 |
+
return bool(osx_version >= (10, 4)) if osx_version else False
|
| 187 |
+
|
| 188 |
+
def _supports_arm64_builds():
|
| 189 |
+
"""Returns True if arm64 builds are supported on this system"""
|
| 190 |
+
# There are two sets of systems supporting macOS/arm64 builds:
|
| 191 |
+
# 1. macOS 11 and later, unconditionally
|
| 192 |
+
# 2. macOS 10.15 with Xcode 12.2 or later
|
| 193 |
+
# For now the second category is ignored.
|
| 194 |
+
osx_version = _get_system_version_tuple()
|
| 195 |
+
return osx_version >= (11, 0) if osx_version else False
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
def _find_appropriate_compiler(_config_vars):
|
| 199 |
+
"""Find appropriate C compiler for extension module builds"""
|
| 200 |
+
|
| 201 |
+
# Issue #13590:
|
| 202 |
+
# The OSX location for the compiler varies between OSX
|
| 203 |
+
# (or rather Xcode) releases. With older releases (up-to 10.5)
|
| 204 |
+
# the compiler is in /usr/bin, with newer releases the compiler
|
| 205 |
+
# can only be found inside Xcode.app if the "Command Line Tools"
|
| 206 |
+
# are not installed.
|
| 207 |
+
#
|
| 208 |
+
# Furthermore, the compiler that can be used varies between
|
| 209 |
+
# Xcode releases. Up to Xcode 4 it was possible to use 'gcc-4.2'
|
| 210 |
+
# as the compiler, after that 'clang' should be used because
|
| 211 |
+
# gcc-4.2 is either not present, or a copy of 'llvm-gcc' that
|
| 212 |
+
# miscompiles Python.
|
| 213 |
+
|
| 214 |
+
# skip checks if the compiler was overridden with a CC env variable
|
| 215 |
+
if 'CC' in os.environ:
|
| 216 |
+
return _config_vars
|
| 217 |
+
|
| 218 |
+
# The CC config var might contain additional arguments.
|
| 219 |
+
# Ignore them while searching.
|
| 220 |
+
cc = oldcc = _config_vars['CC'].split()[0]
|
| 221 |
+
if not _find_executable(cc):
|
| 222 |
+
# Compiler is not found on the shell search PATH.
|
| 223 |
+
# Now search for clang, first on PATH (if the Command LIne
|
| 224 |
+
# Tools have been installed in / or if the user has provided
|
| 225 |
+
# another location via CC). If not found, try using xcrun
|
| 226 |
+
# to find an uninstalled clang (within a selected Xcode).
|
| 227 |
+
|
| 228 |
+
# NOTE: Cannot use subprocess here because of bootstrap
|
| 229 |
+
# issues when building Python itself (and os.popen is
|
| 230 |
+
# implemented on top of subprocess and is therefore not
|
| 231 |
+
# usable as well)
|
| 232 |
+
|
| 233 |
+
cc = _find_build_tool('clang')
|
| 234 |
+
|
| 235 |
+
elif os.path.basename(cc).startswith('gcc'):
|
| 236 |
+
# Compiler is GCC, check if it is LLVM-GCC
|
| 237 |
+
data = _read_output("'%s' --version"
|
| 238 |
+
% (cc.replace("'", "'\"'\"'"),))
|
| 239 |
+
if data and 'llvm-gcc' in data:
|
| 240 |
+
# Found LLVM-GCC, fall back to clang
|
| 241 |
+
cc = _find_build_tool('clang')
|
| 242 |
+
|
| 243 |
+
if not cc:
|
| 244 |
+
raise SystemError(
|
| 245 |
+
"Cannot locate working compiler")
|
| 246 |
+
|
| 247 |
+
if cc != oldcc:
|
| 248 |
+
# Found a replacement compiler.
|
| 249 |
+
# Modify config vars using new compiler, if not already explicitly
|
| 250 |
+
# overridden by an env variable, preserving additional arguments.
|
| 251 |
+
for cv in _COMPILER_CONFIG_VARS:
|
| 252 |
+
if cv in _config_vars and cv not in os.environ:
|
| 253 |
+
cv_split = _config_vars[cv].split()
|
| 254 |
+
cv_split[0] = cc if cv != 'CXX' else cc + '++'
|
| 255 |
+
_save_modified_value(_config_vars, cv, ' '.join(cv_split))
|
| 256 |
+
|
| 257 |
+
return _config_vars
|
| 258 |
+
|
| 259 |
+
|
| 260 |
+
def _remove_universal_flags(_config_vars):
|
| 261 |
+
"""Remove all universal build arguments from config vars"""
|
| 262 |
+
|
| 263 |
+
for cv in _UNIVERSAL_CONFIG_VARS:
|
| 264 |
+
# Do not alter a config var explicitly overridden by env var
|
| 265 |
+
if cv in _config_vars and cv not in os.environ:
|
| 266 |
+
flags = _config_vars[cv]
|
| 267 |
+
flags = re.sub(r'-arch\s+\w+\s', ' ', flags, flags=re.ASCII)
|
| 268 |
+
flags = re.sub(r'-isysroot\s*\S+', ' ', flags)
|
| 269 |
+
_save_modified_value(_config_vars, cv, flags)
|
| 270 |
+
|
| 271 |
+
return _config_vars
|
| 272 |
+
|
| 273 |
+
|
| 274 |
+
def _remove_unsupported_archs(_config_vars):
|
| 275 |
+
"""Remove any unsupported archs from config vars"""
|
| 276 |
+
# Different Xcode releases support different sets for '-arch'
|
| 277 |
+
# flags. In particular, Xcode 4.x no longer supports the
|
| 278 |
+
# PPC architectures.
|
| 279 |
+
#
|
| 280 |
+
# This code automatically removes '-arch ppc' and '-arch ppc64'
|
| 281 |
+
# when these are not supported. That makes it possible to
|
| 282 |
+
# build extensions on OSX 10.7 and later with the prebuilt
|
| 283 |
+
# 32-bit installer on the python.org website.
|
| 284 |
+
|
| 285 |
+
# skip checks if the compiler was overridden with a CC env variable
|
| 286 |
+
if 'CC' in os.environ:
|
| 287 |
+
return _config_vars
|
| 288 |
+
|
| 289 |
+
if re.search(r'-arch\s+ppc', _config_vars['CFLAGS']) is not None:
|
| 290 |
+
# NOTE: Cannot use subprocess here because of bootstrap
|
| 291 |
+
# issues when building Python itself
|
| 292 |
+
status = os.system(
|
| 293 |
+
"""echo 'int main{};' | """
|
| 294 |
+
"""'%s' -c -arch ppc -x c -o /dev/null /dev/null 2>/dev/null"""
|
| 295 |
+
%(_config_vars['CC'].replace("'", "'\"'\"'"),))
|
| 296 |
+
if status:
|
| 297 |
+
# The compile failed for some reason. Because of differences
|
| 298 |
+
# across Xcode and compiler versions, there is no reliable way
|
| 299 |
+
# to be sure why it failed. Assume here it was due to lack of
|
| 300 |
+
# PPC support and remove the related '-arch' flags from each
|
| 301 |
+
# config variables not explicitly overridden by an environment
|
| 302 |
+
# variable. If the error was for some other reason, we hope the
|
| 303 |
+
# failure will show up again when trying to compile an extension
|
| 304 |
+
# module.
|
| 305 |
+
for cv in _UNIVERSAL_CONFIG_VARS:
|
| 306 |
+
if cv in _config_vars and cv not in os.environ:
|
| 307 |
+
flags = _config_vars[cv]
|
| 308 |
+
flags = re.sub(r'-arch\s+ppc\w*\s', ' ', flags)
|
| 309 |
+
_save_modified_value(_config_vars, cv, flags)
|
| 310 |
+
|
| 311 |
+
return _config_vars
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
def _override_all_archs(_config_vars):
|
| 315 |
+
"""Allow override of all archs with ARCHFLAGS env var"""
|
| 316 |
+
# NOTE: This name was introduced by Apple in OSX 10.5 and
|
| 317 |
+
# is used by several scripting languages distributed with
|
| 318 |
+
# that OS release.
|
| 319 |
+
if 'ARCHFLAGS' in os.environ:
|
| 320 |
+
arch = os.environ['ARCHFLAGS']
|
| 321 |
+
for cv in _UNIVERSAL_CONFIG_VARS:
|
| 322 |
+
if cv in _config_vars and '-arch' in _config_vars[cv]:
|
| 323 |
+
flags = _config_vars[cv]
|
| 324 |
+
flags = re.sub(r'-arch\s+\w+\s', ' ', flags)
|
| 325 |
+
flags = flags + ' ' + arch
|
| 326 |
+
_save_modified_value(_config_vars, cv, flags)
|
| 327 |
+
|
| 328 |
+
return _config_vars
|
| 329 |
+
|
| 330 |
+
|
| 331 |
+
def _check_for_unavailable_sdk(_config_vars):
|
| 332 |
+
"""Remove references to any SDKs not available"""
|
| 333 |
+
# If we're on OSX 10.5 or later and the user tries to
|
| 334 |
+
# compile an extension using an SDK that is not present
|
| 335 |
+
# on the current machine it is better to not use an SDK
|
| 336 |
+
# than to fail. This is particularly important with
|
| 337 |
+
# the standalone Command Line Tools alternative to a
|
| 338 |
+
# full-blown Xcode install since the CLT packages do not
|
| 339 |
+
# provide SDKs. If the SDK is not present, it is assumed
|
| 340 |
+
# that the header files and dev libs have been installed
|
| 341 |
+
# to /usr and /System/Library by either a standalone CLT
|
| 342 |
+
# package or the CLT component within Xcode.
|
| 343 |
+
cflags = _config_vars.get('CFLAGS', '')
|
| 344 |
+
m = re.search(r'-isysroot\s*(\S+)', cflags)
|
| 345 |
+
if m is not None:
|
| 346 |
+
sdk = m.group(1)
|
| 347 |
+
if not os.path.exists(sdk):
|
| 348 |
+
for cv in _UNIVERSAL_CONFIG_VARS:
|
| 349 |
+
# Do not alter a config var explicitly overridden by env var
|
| 350 |
+
if cv in _config_vars and cv not in os.environ:
|
| 351 |
+
flags = _config_vars[cv]
|
| 352 |
+
flags = re.sub(r'-isysroot\s*\S+(?:\s|$)', ' ', flags)
|
| 353 |
+
_save_modified_value(_config_vars, cv, flags)
|
| 354 |
+
|
| 355 |
+
return _config_vars
|
| 356 |
+
|
| 357 |
+
|
| 358 |
+
def compiler_fixup(compiler_so, cc_args):
|
| 359 |
+
"""
|
| 360 |
+
This function will strip '-isysroot PATH' and '-arch ARCH' from the
|
| 361 |
+
compile flags if the user has specified one them in extra_compile_flags.
|
| 362 |
+
|
| 363 |
+
This is needed because '-arch ARCH' adds another architecture to the
|
| 364 |
+
build, without a way to remove an architecture. Furthermore GCC will
|
| 365 |
+
barf if multiple '-isysroot' arguments are present.
|
| 366 |
+
"""
|
| 367 |
+
stripArch = stripSysroot = False
|
| 368 |
+
|
| 369 |
+
compiler_so = list(compiler_so)
|
| 370 |
+
|
| 371 |
+
if not _supports_universal_builds():
|
| 372 |
+
# OSX before 10.4.0, these don't support -arch and -isysroot at
|
| 373 |
+
# all.
|
| 374 |
+
stripArch = stripSysroot = True
|
| 375 |
+
else:
|
| 376 |
+
stripArch = '-arch' in cc_args
|
| 377 |
+
stripSysroot = any(arg for arg in cc_args if arg.startswith('-isysroot'))
|
| 378 |
+
|
| 379 |
+
if stripArch or 'ARCHFLAGS' in os.environ:
|
| 380 |
+
while True:
|
| 381 |
+
try:
|
| 382 |
+
index = compiler_so.index('-arch')
|
| 383 |
+
# Strip this argument and the next one:
|
| 384 |
+
del compiler_so[index:index+2]
|
| 385 |
+
except ValueError:
|
| 386 |
+
break
|
| 387 |
+
|
| 388 |
+
elif not _supports_arm64_builds():
|
| 389 |
+
# Look for "-arch arm64" and drop that
|
| 390 |
+
for idx in reversed(range(len(compiler_so))):
|
| 391 |
+
if compiler_so[idx] == '-arch' and compiler_so[idx+1] == "arm64":
|
| 392 |
+
del compiler_so[idx:idx+2]
|
| 393 |
+
|
| 394 |
+
if 'ARCHFLAGS' in os.environ and not stripArch:
|
| 395 |
+
# User specified different -arch flags in the environ,
|
| 396 |
+
# see also distutils.sysconfig
|
| 397 |
+
compiler_so = compiler_so + os.environ['ARCHFLAGS'].split()
|
| 398 |
+
|
| 399 |
+
if stripSysroot:
|
| 400 |
+
while True:
|
| 401 |
+
indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')]
|
| 402 |
+
if not indices:
|
| 403 |
+
break
|
| 404 |
+
index = indices[0]
|
| 405 |
+
if compiler_so[index] == '-isysroot':
|
| 406 |
+
# Strip this argument and the next one:
|
| 407 |
+
del compiler_so[index:index+2]
|
| 408 |
+
else:
|
| 409 |
+
# It's '-isysroot/some/path' in one arg
|
| 410 |
+
del compiler_so[index:index+1]
|
| 411 |
+
|
| 412 |
+
# Check if the SDK that is used during compilation actually exists,
|
| 413 |
+
# the universal build requires the usage of a universal SDK and not all
|
| 414 |
+
# users have that installed by default.
|
| 415 |
+
sysroot = None
|
| 416 |
+
argvar = cc_args
|
| 417 |
+
indices = [i for i,x in enumerate(cc_args) if x.startswith('-isysroot')]
|
| 418 |
+
if not indices:
|
| 419 |
+
argvar = compiler_so
|
| 420 |
+
indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')]
|
| 421 |
+
|
| 422 |
+
for idx in indices:
|
| 423 |
+
if argvar[idx] == '-isysroot':
|
| 424 |
+
sysroot = argvar[idx+1]
|
| 425 |
+
break
|
| 426 |
+
else:
|
| 427 |
+
sysroot = argvar[idx][len('-isysroot'):]
|
| 428 |
+
break
|
| 429 |
+
|
| 430 |
+
if sysroot and not os.path.isdir(sysroot):
|
| 431 |
+
from distutils import log
|
| 432 |
+
log.warn("Compiling with an SDK that doesn't seem to exist: %s",
|
| 433 |
+
sysroot)
|
| 434 |
+
log.warn("Please check your Xcode installation")
|
| 435 |
+
|
| 436 |
+
return compiler_so
|
| 437 |
+
|
| 438 |
+
|
| 439 |
+
def customize_config_vars(_config_vars):
|
| 440 |
+
"""Customize Python build configuration variables.
|
| 441 |
+
|
| 442 |
+
Called internally from sysconfig with a mutable mapping
|
| 443 |
+
containing name/value pairs parsed from the configured
|
| 444 |
+
makefile used to build this interpreter. Returns
|
| 445 |
+
the mapping updated as needed to reflect the environment
|
| 446 |
+
in which the interpreter is running; in the case of
|
| 447 |
+
a Python from a binary installer, the installed
|
| 448 |
+
environment may be very different from the build
|
| 449 |
+
environment, i.e. different OS levels, different
|
| 450 |
+
built tools, different available CPU architectures.
|
| 451 |
+
|
| 452 |
+
This customization is performed whenever
|
| 453 |
+
distutils.sysconfig.get_config_vars() is first
|
| 454 |
+
called. It may be used in environments where no
|
| 455 |
+
compilers are present, i.e. when installing pure
|
| 456 |
+
Python dists. Customization of compiler paths
|
| 457 |
+
and detection of unavailable archs is deferred
|
| 458 |
+
until the first extension module build is
|
| 459 |
+
requested (in distutils.sysconfig.customize_compiler).
|
| 460 |
+
|
| 461 |
+
Currently called from distutils.sysconfig
|
| 462 |
+
"""
|
| 463 |
+
|
| 464 |
+
if not _supports_universal_builds():
|
| 465 |
+
# On Mac OS X before 10.4, check if -arch and -isysroot
|
| 466 |
+
# are in CFLAGS or LDFLAGS and remove them if they are.
|
| 467 |
+
# This is needed when building extensions on a 10.3 system
|
| 468 |
+
# using a universal build of python.
|
| 469 |
+
_remove_universal_flags(_config_vars)
|
| 470 |
+
|
| 471 |
+
# Allow user to override all archs with ARCHFLAGS env var
|
| 472 |
+
_override_all_archs(_config_vars)
|
| 473 |
+
|
| 474 |
+
# Remove references to sdks that are not found
|
| 475 |
+
_check_for_unavailable_sdk(_config_vars)
|
| 476 |
+
|
| 477 |
+
return _config_vars
|
| 478 |
+
|
| 479 |
+
|
| 480 |
+
def customize_compiler(_config_vars):
|
| 481 |
+
"""Customize compiler path and configuration variables.
|
| 482 |
+
|
| 483 |
+
This customization is performed when the first
|
| 484 |
+
extension module build is requested
|
| 485 |
+
in distutils.sysconfig.customize_compiler).
|
| 486 |
+
"""
|
| 487 |
+
|
| 488 |
+
# Find a compiler to use for extension module builds
|
| 489 |
+
_find_appropriate_compiler(_config_vars)
|
| 490 |
+
|
| 491 |
+
# Remove ppc arch flags if not supported here
|
| 492 |
+
_remove_unsupported_archs(_config_vars)
|
| 493 |
+
|
| 494 |
+
# Allow user to override all archs with ARCHFLAGS env var
|
| 495 |
+
_override_all_archs(_config_vars)
|
| 496 |
+
|
| 497 |
+
return _config_vars
|
| 498 |
+
|
| 499 |
+
|
| 500 |
+
def get_platform_osx(_config_vars, osname, release, machine):
|
| 501 |
+
"""Filter values for get_platform()"""
|
| 502 |
+
# called from get_platform() in sysconfig and distutils.util
|
| 503 |
+
#
|
| 504 |
+
# For our purposes, we'll assume that the system version from
|
| 505 |
+
# distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set
|
| 506 |
+
# to. This makes the compatibility story a bit more sane because the
|
| 507 |
+
# machine is going to compile and link as if it were
|
| 508 |
+
# MACOSX_DEPLOYMENT_TARGET.
|
| 509 |
+
|
| 510 |
+
macver = _config_vars.get('MACOSX_DEPLOYMENT_TARGET', '')
|
| 511 |
+
macrelease = _get_system_version() or macver
|
| 512 |
+
macver = macver or macrelease
|
| 513 |
+
|
| 514 |
+
if macver:
|
| 515 |
+
release = macver
|
| 516 |
+
osname = "macosx"
|
| 517 |
+
|
| 518 |
+
# Use the original CFLAGS value, if available, so that we
|
| 519 |
+
# return the same machine type for the platform string.
|
| 520 |
+
# Otherwise, distutils may consider this a cross-compiling
|
| 521 |
+
# case and disallow installs.
|
| 522 |
+
cflags = _config_vars.get(_INITPRE+'CFLAGS',
|
| 523 |
+
_config_vars.get('CFLAGS', ''))
|
| 524 |
+
if macrelease:
|
| 525 |
+
try:
|
| 526 |
+
macrelease = tuple(int(i) for i in macrelease.split('.')[0:2])
|
| 527 |
+
except ValueError:
|
| 528 |
+
macrelease = (10, 0)
|
| 529 |
+
else:
|
| 530 |
+
# assume no universal support
|
| 531 |
+
macrelease = (10, 0)
|
| 532 |
+
|
| 533 |
+
if (macrelease >= (10, 4)) and '-arch' in cflags.strip():
|
| 534 |
+
# The universal build will build fat binaries, but not on
|
| 535 |
+
# systems before 10.4
|
| 536 |
+
|
| 537 |
+
machine = 'fat'
|
| 538 |
+
|
| 539 |
+
archs = re.findall(r'-arch\s+(\S+)', cflags)
|
| 540 |
+
archs = tuple(sorted(set(archs)))
|
| 541 |
+
|
| 542 |
+
if len(archs) == 1:
|
| 543 |
+
machine = archs[0]
|
| 544 |
+
elif archs == ('arm64', 'x86_64'):
|
| 545 |
+
machine = 'universal2'
|
| 546 |
+
elif archs == ('i386', 'ppc'):
|
| 547 |
+
machine = 'fat'
|
| 548 |
+
elif archs == ('i386', 'x86_64'):
|
| 549 |
+
machine = 'intel'
|
| 550 |
+
elif archs == ('i386', 'ppc', 'x86_64'):
|
| 551 |
+
machine = 'fat3'
|
| 552 |
+
elif archs == ('ppc64', 'x86_64'):
|
| 553 |
+
machine = 'fat64'
|
| 554 |
+
elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'):
|
| 555 |
+
machine = 'universal'
|
| 556 |
+
else:
|
| 557 |
+
raise ValueError(
|
| 558 |
+
"Don't know machine value for archs=%r" % (archs,))
|
| 559 |
+
|
| 560 |
+
elif machine == 'i386':
|
| 561 |
+
# On OSX the machine type returned by uname is always the
|
| 562 |
+
# 32-bit variant, even if the executable architecture is
|
| 563 |
+
# the 64-bit variant
|
| 564 |
+
if sys.maxsize >= 2**32:
|
| 565 |
+
machine = 'x86_64'
|
| 566 |
+
|
| 567 |
+
elif machine in ('PowerPC', 'Power_Macintosh'):
|
| 568 |
+
# Pick a sane name for the PPC architecture.
|
| 569 |
+
# See 'i386' case
|
| 570 |
+
if sys.maxsize >= 2**32:
|
| 571 |
+
machine = 'ppc64'
|
| 572 |
+
else:
|
| 573 |
+
machine = 'ppc'
|
| 574 |
+
|
| 575 |
+
return (osname, release, machine)
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/_sitebuiltins.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
The objects used by the site module to add custom builtins.
|
| 3 |
+
"""
|
| 4 |
+
|
| 5 |
+
# Those objects are almost immortal and they keep a reference to their module
|
| 6 |
+
# globals. Defining them in the site module would keep too many references
|
| 7 |
+
# alive.
|
| 8 |
+
# Note this means this module should also avoid keep things alive in its
|
| 9 |
+
# globals.
|
| 10 |
+
|
| 11 |
+
import sys
|
| 12 |
+
|
| 13 |
+
class Quitter(object):
|
| 14 |
+
def __init__(self, name, eof):
|
| 15 |
+
self.name = name
|
| 16 |
+
self.eof = eof
|
| 17 |
+
def __repr__(self):
|
| 18 |
+
return 'Use %s() or %s to exit' % (self.name, self.eof)
|
| 19 |
+
def __call__(self, code=None):
|
| 20 |
+
# Shells like IDLE catch the SystemExit, but listen when their
|
| 21 |
+
# stdin wrapper is closed.
|
| 22 |
+
try:
|
| 23 |
+
sys.stdin.close()
|
| 24 |
+
except:
|
| 25 |
+
pass
|
| 26 |
+
raise SystemExit(code)
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
class _Printer(object):
|
| 30 |
+
"""interactive prompt objects for printing the license text, a list of
|
| 31 |
+
contributors and the copyright notice."""
|
| 32 |
+
|
| 33 |
+
MAXLINES = 23
|
| 34 |
+
|
| 35 |
+
def __init__(self, name, data, files=(), dirs=()):
|
| 36 |
+
import os
|
| 37 |
+
self.__name = name
|
| 38 |
+
self.__data = data
|
| 39 |
+
self.__lines = None
|
| 40 |
+
self.__filenames = [os.path.join(dir, filename)
|
| 41 |
+
for dir in dirs
|
| 42 |
+
for filename in files]
|
| 43 |
+
|
| 44 |
+
def __setup(self):
|
| 45 |
+
if self.__lines:
|
| 46 |
+
return
|
| 47 |
+
data = None
|
| 48 |
+
for filename in self.__filenames:
|
| 49 |
+
try:
|
| 50 |
+
with open(filename, "r") as fp:
|
| 51 |
+
data = fp.read()
|
| 52 |
+
break
|
| 53 |
+
except OSError:
|
| 54 |
+
pass
|
| 55 |
+
if not data:
|
| 56 |
+
data = self.__data
|
| 57 |
+
self.__lines = data.split('\n')
|
| 58 |
+
self.__linecnt = len(self.__lines)
|
| 59 |
+
|
| 60 |
+
def __repr__(self):
|
| 61 |
+
self.__setup()
|
| 62 |
+
if len(self.__lines) <= self.MAXLINES:
|
| 63 |
+
return "\n".join(self.__lines)
|
| 64 |
+
else:
|
| 65 |
+
return "Type %s() to see the full %s text" % ((self.__name,)*2)
|
| 66 |
+
|
| 67 |
+
def __call__(self):
|
| 68 |
+
self.__setup()
|
| 69 |
+
prompt = 'Hit Return for more, or q (and Return) to quit: '
|
| 70 |
+
lineno = 0
|
| 71 |
+
while 1:
|
| 72 |
+
try:
|
| 73 |
+
for i in range(lineno, lineno + self.MAXLINES):
|
| 74 |
+
print(self.__lines[i])
|
| 75 |
+
except IndexError:
|
| 76 |
+
break
|
| 77 |
+
else:
|
| 78 |
+
lineno += self.MAXLINES
|
| 79 |
+
key = None
|
| 80 |
+
while key is None:
|
| 81 |
+
key = input(prompt)
|
| 82 |
+
if key not in ('', 'q'):
|
| 83 |
+
key = None
|
| 84 |
+
if key == 'q':
|
| 85 |
+
break
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
class _Helper(object):
|
| 89 |
+
"""Define the builtin 'help'.
|
| 90 |
+
|
| 91 |
+
This is a wrapper around pydoc.help that provides a helpful message
|
| 92 |
+
when 'help' is typed at the Python interactive prompt.
|
| 93 |
+
|
| 94 |
+
Calling help() at the Python prompt starts an interactive help session.
|
| 95 |
+
Calling help(thing) prints help for the python object 'thing'.
|
| 96 |
+
"""
|
| 97 |
+
|
| 98 |
+
def __repr__(self):
|
| 99 |
+
return "Type help() for interactive help, " \
|
| 100 |
+
"or help(object) for help about object."
|
| 101 |
+
def __call__(self, *args, **kwds):
|
| 102 |
+
import pydoc
|
| 103 |
+
return pydoc.help(*args, **kwds)
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/_strptime.py
ADDED
|
@@ -0,0 +1,579 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Strptime-related classes and functions.
|
| 2 |
+
|
| 3 |
+
CLASSES:
|
| 4 |
+
LocaleTime -- Discovers and stores locale-specific time information
|
| 5 |
+
TimeRE -- Creates regexes for pattern matching a string of text containing
|
| 6 |
+
time information
|
| 7 |
+
|
| 8 |
+
FUNCTIONS:
|
| 9 |
+
_getlang -- Figure out what language is being used for the locale
|
| 10 |
+
strptime -- Calculates the time struct represented by the passed-in string
|
| 11 |
+
|
| 12 |
+
"""
|
| 13 |
+
import time
|
| 14 |
+
import locale
|
| 15 |
+
import calendar
|
| 16 |
+
from re import compile as re_compile
|
| 17 |
+
from re import IGNORECASE
|
| 18 |
+
from re import escape as re_escape
|
| 19 |
+
from datetime import (date as datetime_date,
|
| 20 |
+
timedelta as datetime_timedelta,
|
| 21 |
+
timezone as datetime_timezone)
|
| 22 |
+
from _thread import allocate_lock as _thread_allocate_lock
|
| 23 |
+
|
| 24 |
+
__all__ = []
|
| 25 |
+
|
| 26 |
+
def _getlang():
|
| 27 |
+
# Figure out what the current language is set to.
|
| 28 |
+
return locale.getlocale(locale.LC_TIME)
|
| 29 |
+
|
| 30 |
+
class LocaleTime(object):
|
| 31 |
+
"""Stores and handles locale-specific information related to time.
|
| 32 |
+
|
| 33 |
+
ATTRIBUTES:
|
| 34 |
+
f_weekday -- full weekday names (7-item list)
|
| 35 |
+
a_weekday -- abbreviated weekday names (7-item list)
|
| 36 |
+
f_month -- full month names (13-item list; dummy value in [0], which
|
| 37 |
+
is added by code)
|
| 38 |
+
a_month -- abbreviated month names (13-item list, dummy value in
|
| 39 |
+
[0], which is added by code)
|
| 40 |
+
am_pm -- AM/PM representation (2-item list)
|
| 41 |
+
LC_date_time -- format string for date/time representation (string)
|
| 42 |
+
LC_date -- format string for date representation (string)
|
| 43 |
+
LC_time -- format string for time representation (string)
|
| 44 |
+
timezone -- daylight- and non-daylight-savings timezone representation
|
| 45 |
+
(2-item list of sets)
|
| 46 |
+
lang -- Language used by instance (2-item tuple)
|
| 47 |
+
"""
|
| 48 |
+
|
| 49 |
+
def __init__(self):
|
| 50 |
+
"""Set all attributes.
|
| 51 |
+
|
| 52 |
+
Order of methods called matters for dependency reasons.
|
| 53 |
+
|
| 54 |
+
The locale language is set at the offset and then checked again before
|
| 55 |
+
exiting. This is to make sure that the attributes were not set with a
|
| 56 |
+
mix of information from more than one locale. This would most likely
|
| 57 |
+
happen when using threads where one thread calls a locale-dependent
|
| 58 |
+
function while another thread changes the locale while the function in
|
| 59 |
+
the other thread is still running. Proper coding would call for
|
| 60 |
+
locks to prevent changing the locale while locale-dependent code is
|
| 61 |
+
running. The check here is done in case someone does not think about
|
| 62 |
+
doing this.
|
| 63 |
+
|
| 64 |
+
Only other possible issue is if someone changed the timezone and did
|
| 65 |
+
not call tz.tzset . That is an issue for the programmer, though,
|
| 66 |
+
since changing the timezone is worthless without that call.
|
| 67 |
+
|
| 68 |
+
"""
|
| 69 |
+
self.lang = _getlang()
|
| 70 |
+
self.__calc_weekday()
|
| 71 |
+
self.__calc_month()
|
| 72 |
+
self.__calc_am_pm()
|
| 73 |
+
self.__calc_timezone()
|
| 74 |
+
self.__calc_date_time()
|
| 75 |
+
if _getlang() != self.lang:
|
| 76 |
+
raise ValueError("locale changed during initialization")
|
| 77 |
+
if time.tzname != self.tzname or time.daylight != self.daylight:
|
| 78 |
+
raise ValueError("timezone changed during initialization")
|
| 79 |
+
|
| 80 |
+
def __calc_weekday(self):
|
| 81 |
+
# Set self.a_weekday and self.f_weekday using the calendar
|
| 82 |
+
# module.
|
| 83 |
+
a_weekday = [calendar.day_abbr[i].lower() for i in range(7)]
|
| 84 |
+
f_weekday = [calendar.day_name[i].lower() for i in range(7)]
|
| 85 |
+
self.a_weekday = a_weekday
|
| 86 |
+
self.f_weekday = f_weekday
|
| 87 |
+
|
| 88 |
+
def __calc_month(self):
|
| 89 |
+
# Set self.f_month and self.a_month using the calendar module.
|
| 90 |
+
a_month = [calendar.month_abbr[i].lower() for i in range(13)]
|
| 91 |
+
f_month = [calendar.month_name[i].lower() for i in range(13)]
|
| 92 |
+
self.a_month = a_month
|
| 93 |
+
self.f_month = f_month
|
| 94 |
+
|
| 95 |
+
def __calc_am_pm(self):
|
| 96 |
+
# Set self.am_pm by using time.strftime().
|
| 97 |
+
|
| 98 |
+
# The magic date (1999,3,17,hour,44,55,2,76,0) is not really that
|
| 99 |
+
# magical; just happened to have used it everywhere else where a
|
| 100 |
+
# static date was needed.
|
| 101 |
+
am_pm = []
|
| 102 |
+
for hour in (1, 22):
|
| 103 |
+
time_tuple = time.struct_time((1999,3,17,hour,44,55,2,76,0))
|
| 104 |
+
am_pm.append(time.strftime("%p", time_tuple).lower())
|
| 105 |
+
self.am_pm = am_pm
|
| 106 |
+
|
| 107 |
+
def __calc_date_time(self):
|
| 108 |
+
# Set self.date_time, self.date, & self.time by using
|
| 109 |
+
# time.strftime().
|
| 110 |
+
|
| 111 |
+
# Use (1999,3,17,22,44,55,2,76,0) for magic date because the amount of
|
| 112 |
+
# overloaded numbers is minimized. The order in which searches for
|
| 113 |
+
# values within the format string is very important; it eliminates
|
| 114 |
+
# possible ambiguity for what something represents.
|
| 115 |
+
time_tuple = time.struct_time((1999,3,17,22,44,55,2,76,0))
|
| 116 |
+
date_time = [None, None, None]
|
| 117 |
+
date_time[0] = time.strftime("%c", time_tuple).lower()
|
| 118 |
+
date_time[1] = time.strftime("%x", time_tuple).lower()
|
| 119 |
+
date_time[2] = time.strftime("%X", time_tuple).lower()
|
| 120 |
+
replacement_pairs = [('%', '%%'), (self.f_weekday[2], '%A'),
|
| 121 |
+
(self.f_month[3], '%B'), (self.a_weekday[2], '%a'),
|
| 122 |
+
(self.a_month[3], '%b'), (self.am_pm[1], '%p'),
|
| 123 |
+
('1999', '%Y'), ('99', '%y'), ('22', '%H'),
|
| 124 |
+
('44', '%M'), ('55', '%S'), ('76', '%j'),
|
| 125 |
+
('17', '%d'), ('03', '%m'), ('3', '%m'),
|
| 126 |
+
# '3' needed for when no leading zero.
|
| 127 |
+
('2', '%w'), ('10', '%I')]
|
| 128 |
+
replacement_pairs.extend([(tz, "%Z") for tz_values in self.timezone
|
| 129 |
+
for tz in tz_values])
|
| 130 |
+
for offset,directive in ((0,'%c'), (1,'%x'), (2,'%X')):
|
| 131 |
+
current_format = date_time[offset]
|
| 132 |
+
for old, new in replacement_pairs:
|
| 133 |
+
# Must deal with possible lack of locale info
|
| 134 |
+
# manifesting itself as the empty string (e.g., Swedish's
|
| 135 |
+
# lack of AM/PM info) or a platform returning a tuple of empty
|
| 136 |
+
# strings (e.g., MacOS 9 having timezone as ('','')).
|
| 137 |
+
if old:
|
| 138 |
+
current_format = current_format.replace(old, new)
|
| 139 |
+
# If %W is used, then Sunday, 2005-01-03 will fall on week 0 since
|
| 140 |
+
# 2005-01-03 occurs before the first Monday of the year. Otherwise
|
| 141 |
+
# %U is used.
|
| 142 |
+
time_tuple = time.struct_time((1999,1,3,1,1,1,6,3,0))
|
| 143 |
+
if '00' in time.strftime(directive, time_tuple):
|
| 144 |
+
U_W = '%W'
|
| 145 |
+
else:
|
| 146 |
+
U_W = '%U'
|
| 147 |
+
date_time[offset] = current_format.replace('11', U_W)
|
| 148 |
+
self.LC_date_time = date_time[0]
|
| 149 |
+
self.LC_date = date_time[1]
|
| 150 |
+
self.LC_time = date_time[2]
|
| 151 |
+
|
| 152 |
+
def __calc_timezone(self):
|
| 153 |
+
# Set self.timezone by using time.tzname.
|
| 154 |
+
# Do not worry about possibility of time.tzname[0] == time.tzname[1]
|
| 155 |
+
# and time.daylight; handle that in strptime.
|
| 156 |
+
try:
|
| 157 |
+
time.tzset()
|
| 158 |
+
except AttributeError:
|
| 159 |
+
pass
|
| 160 |
+
self.tzname = time.tzname
|
| 161 |
+
self.daylight = time.daylight
|
| 162 |
+
no_saving = frozenset({"utc", "gmt", self.tzname[0].lower()})
|
| 163 |
+
if self.daylight:
|
| 164 |
+
has_saving = frozenset({self.tzname[1].lower()})
|
| 165 |
+
else:
|
| 166 |
+
has_saving = frozenset()
|
| 167 |
+
self.timezone = (no_saving, has_saving)
|
| 168 |
+
|
| 169 |
+
|
| 170 |
+
class TimeRE(dict):
|
| 171 |
+
"""Handle conversion from format directives to regexes."""
|
| 172 |
+
|
| 173 |
+
def __init__(self, locale_time=None):
|
| 174 |
+
"""Create keys/values.
|
| 175 |
+
|
| 176 |
+
Order of execution is important for dependency reasons.
|
| 177 |
+
|
| 178 |
+
"""
|
| 179 |
+
if locale_time:
|
| 180 |
+
self.locale_time = locale_time
|
| 181 |
+
else:
|
| 182 |
+
self.locale_time = LocaleTime()
|
| 183 |
+
base = super()
|
| 184 |
+
base.__init__({
|
| 185 |
+
# The " \d" part of the regex is to make %c from ANSI C work
|
| 186 |
+
'd': r"(?P<d>3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])",
|
| 187 |
+
'f': r"(?P<f>[0-9]{1,6})",
|
| 188 |
+
'H': r"(?P<H>2[0-3]|[0-1]\d|\d)",
|
| 189 |
+
'I': r"(?P<I>1[0-2]|0[1-9]|[1-9])",
|
| 190 |
+
'G': r"(?P<G>\d\d\d\d)",
|
| 191 |
+
'j': r"(?P<j>36[0-6]|3[0-5]\d|[1-2]\d\d|0[1-9]\d|00[1-9]|[1-9]\d|0[1-9]|[1-9])",
|
| 192 |
+
'm': r"(?P<m>1[0-2]|0[1-9]|[1-9])",
|
| 193 |
+
'M': r"(?P<M>[0-5]\d|\d)",
|
| 194 |
+
'S': r"(?P<S>6[0-1]|[0-5]\d|\d)",
|
| 195 |
+
'U': r"(?P<U>5[0-3]|[0-4]\d|\d)",
|
| 196 |
+
'w': r"(?P<w>[0-6])",
|
| 197 |
+
'u': r"(?P<u>[1-7])",
|
| 198 |
+
'V': r"(?P<V>5[0-3]|0[1-9]|[1-4]\d|\d)",
|
| 199 |
+
# W is set below by using 'U'
|
| 200 |
+
'y': r"(?P<y>\d\d)",
|
| 201 |
+
#XXX: Does 'Y' need to worry about having less or more than
|
| 202 |
+
# 4 digits?
|
| 203 |
+
'Y': r"(?P<Y>\d\d\d\d)",
|
| 204 |
+
'z': r"(?P<z>[+-]\d\d:?[0-5]\d(:?[0-5]\d(\.\d{1,6})?)?|Z)",
|
| 205 |
+
'A': self.__seqToRE(self.locale_time.f_weekday, 'A'),
|
| 206 |
+
'a': self.__seqToRE(self.locale_time.a_weekday, 'a'),
|
| 207 |
+
'B': self.__seqToRE(self.locale_time.f_month[1:], 'B'),
|
| 208 |
+
'b': self.__seqToRE(self.locale_time.a_month[1:], 'b'),
|
| 209 |
+
'p': self.__seqToRE(self.locale_time.am_pm, 'p'),
|
| 210 |
+
'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone
|
| 211 |
+
for tz in tz_names),
|
| 212 |
+
'Z'),
|
| 213 |
+
'%': '%'})
|
| 214 |
+
base.__setitem__('W', base.__getitem__('U').replace('U', 'W'))
|
| 215 |
+
base.__setitem__('c', self.pattern(self.locale_time.LC_date_time))
|
| 216 |
+
base.__setitem__('x', self.pattern(self.locale_time.LC_date))
|
| 217 |
+
base.__setitem__('X', self.pattern(self.locale_time.LC_time))
|
| 218 |
+
|
| 219 |
+
def __seqToRE(self, to_convert, directive):
|
| 220 |
+
"""Convert a list to a regex string for matching a directive.
|
| 221 |
+
|
| 222 |
+
Want possible matching values to be from longest to shortest. This
|
| 223 |
+
prevents the possibility of a match occurring for a value that also
|
| 224 |
+
a substring of a larger value that should have matched (e.g., 'abc'
|
| 225 |
+
matching when 'abcdef' should have been the match).
|
| 226 |
+
|
| 227 |
+
"""
|
| 228 |
+
to_convert = sorted(to_convert, key=len, reverse=True)
|
| 229 |
+
for value in to_convert:
|
| 230 |
+
if value != '':
|
| 231 |
+
break
|
| 232 |
+
else:
|
| 233 |
+
return ''
|
| 234 |
+
regex = '|'.join(re_escape(stuff) for stuff in to_convert)
|
| 235 |
+
regex = '(?P<%s>%s' % (directive, regex)
|
| 236 |
+
return '%s)' % regex
|
| 237 |
+
|
| 238 |
+
def pattern(self, format):
|
| 239 |
+
"""Return regex pattern for the format string.
|
| 240 |
+
|
| 241 |
+
Need to make sure that any characters that might be interpreted as
|
| 242 |
+
regex syntax are escaped.
|
| 243 |
+
|
| 244 |
+
"""
|
| 245 |
+
processed_format = ''
|
| 246 |
+
# The sub() call escapes all characters that might be misconstrued
|
| 247 |
+
# as regex syntax. Cannot use re.escape since we have to deal with
|
| 248 |
+
# format directives (%m, etc.).
|
| 249 |
+
regex_chars = re_compile(r"([\\.^$*+?\(\){}\[\]|])")
|
| 250 |
+
format = regex_chars.sub(r"\\\1", format)
|
| 251 |
+
whitespace_replacement = re_compile(r'\s+')
|
| 252 |
+
format = whitespace_replacement.sub(r'\\s+', format)
|
| 253 |
+
while '%' in format:
|
| 254 |
+
directive_index = format.index('%')+1
|
| 255 |
+
processed_format = "%s%s%s" % (processed_format,
|
| 256 |
+
format[:directive_index-1],
|
| 257 |
+
self[format[directive_index]])
|
| 258 |
+
format = format[directive_index+1:]
|
| 259 |
+
return "%s%s" % (processed_format, format)
|
| 260 |
+
|
| 261 |
+
def compile(self, format):
|
| 262 |
+
"""Return a compiled re object for the format string."""
|
| 263 |
+
return re_compile(self.pattern(format), IGNORECASE)
|
| 264 |
+
|
| 265 |
+
_cache_lock = _thread_allocate_lock()
|
| 266 |
+
# DO NOT modify _TimeRE_cache or _regex_cache without acquiring the cache lock
|
| 267 |
+
# first!
|
| 268 |
+
_TimeRE_cache = TimeRE()
|
| 269 |
+
_CACHE_MAX_SIZE = 5 # Max number of regexes stored in _regex_cache
|
| 270 |
+
_regex_cache = {}
|
| 271 |
+
|
| 272 |
+
def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon):
|
| 273 |
+
"""Calculate the Julian day based on the year, week of the year, and day of
|
| 274 |
+
the week, with week_start_day representing whether the week of the year
|
| 275 |
+
assumes the week starts on Sunday or Monday (6 or 0)."""
|
| 276 |
+
first_weekday = datetime_date(year, 1, 1).weekday()
|
| 277 |
+
# If we are dealing with the %U directive (week starts on Sunday), it's
|
| 278 |
+
# easier to just shift the view to Sunday being the first day of the
|
| 279 |
+
# week.
|
| 280 |
+
if not week_starts_Mon:
|
| 281 |
+
first_weekday = (first_weekday + 1) % 7
|
| 282 |
+
day_of_week = (day_of_week + 1) % 7
|
| 283 |
+
# Need to watch out for a week 0 (when the first day of the year is not
|
| 284 |
+
# the same as that specified by %U or %W).
|
| 285 |
+
week_0_length = (7 - first_weekday) % 7
|
| 286 |
+
if week_of_year == 0:
|
| 287 |
+
return 1 + day_of_week - first_weekday
|
| 288 |
+
else:
|
| 289 |
+
days_to_week = week_0_length + (7 * (week_of_year - 1))
|
| 290 |
+
return 1 + days_to_week + day_of_week
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
def _calc_julian_from_V(iso_year, iso_week, iso_weekday):
|
| 294 |
+
"""Calculate the Julian day based on the ISO 8601 year, week, and weekday.
|
| 295 |
+
ISO weeks start on Mondays, with week 01 being the week containing 4 Jan.
|
| 296 |
+
ISO week days range from 1 (Monday) to 7 (Sunday).
|
| 297 |
+
"""
|
| 298 |
+
correction = datetime_date(iso_year, 1, 4).isoweekday() + 3
|
| 299 |
+
ordinal = (iso_week * 7) + iso_weekday - correction
|
| 300 |
+
# ordinal may be negative or 0 now, which means the date is in the previous
|
| 301 |
+
# calendar year
|
| 302 |
+
if ordinal < 1:
|
| 303 |
+
ordinal += datetime_date(iso_year, 1, 1).toordinal()
|
| 304 |
+
iso_year -= 1
|
| 305 |
+
ordinal -= datetime_date(iso_year, 1, 1).toordinal()
|
| 306 |
+
return iso_year, ordinal
|
| 307 |
+
|
| 308 |
+
|
| 309 |
+
def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
|
| 310 |
+
"""Return a 2-tuple consisting of a time struct and an int containing
|
| 311 |
+
the number of microseconds based on the input string and the
|
| 312 |
+
format string."""
|
| 313 |
+
|
| 314 |
+
for index, arg in enumerate([data_string, format]):
|
| 315 |
+
if not isinstance(arg, str):
|
| 316 |
+
msg = "strptime() argument {} must be str, not {}"
|
| 317 |
+
raise TypeError(msg.format(index, type(arg)))
|
| 318 |
+
|
| 319 |
+
global _TimeRE_cache, _regex_cache
|
| 320 |
+
with _cache_lock:
|
| 321 |
+
locale_time = _TimeRE_cache.locale_time
|
| 322 |
+
if (_getlang() != locale_time.lang or
|
| 323 |
+
time.tzname != locale_time.tzname or
|
| 324 |
+
time.daylight != locale_time.daylight):
|
| 325 |
+
_TimeRE_cache = TimeRE()
|
| 326 |
+
_regex_cache.clear()
|
| 327 |
+
locale_time = _TimeRE_cache.locale_time
|
| 328 |
+
if len(_regex_cache) > _CACHE_MAX_SIZE:
|
| 329 |
+
_regex_cache.clear()
|
| 330 |
+
format_regex = _regex_cache.get(format)
|
| 331 |
+
if not format_regex:
|
| 332 |
+
try:
|
| 333 |
+
format_regex = _TimeRE_cache.compile(format)
|
| 334 |
+
# KeyError raised when a bad format is found; can be specified as
|
| 335 |
+
# \\, in which case it was a stray % but with a space after it
|
| 336 |
+
except KeyError as err:
|
| 337 |
+
bad_directive = err.args[0]
|
| 338 |
+
if bad_directive == "\\":
|
| 339 |
+
bad_directive = "%"
|
| 340 |
+
del err
|
| 341 |
+
raise ValueError("'%s' is a bad directive in format '%s'" %
|
| 342 |
+
(bad_directive, format)) from None
|
| 343 |
+
# IndexError only occurs when the format string is "%"
|
| 344 |
+
except IndexError:
|
| 345 |
+
raise ValueError("stray %% in format '%s'" % format) from None
|
| 346 |
+
_regex_cache[format] = format_regex
|
| 347 |
+
found = format_regex.match(data_string)
|
| 348 |
+
if not found:
|
| 349 |
+
raise ValueError("time data %r does not match format %r" %
|
| 350 |
+
(data_string, format))
|
| 351 |
+
if len(data_string) != found.end():
|
| 352 |
+
raise ValueError("unconverted data remains: %s" %
|
| 353 |
+
data_string[found.end():])
|
| 354 |
+
|
| 355 |
+
iso_year = year = None
|
| 356 |
+
month = day = 1
|
| 357 |
+
hour = minute = second = fraction = 0
|
| 358 |
+
tz = -1
|
| 359 |
+
gmtoff = None
|
| 360 |
+
gmtoff_fraction = 0
|
| 361 |
+
# Default to -1 to signify that values not known; not critical to have,
|
| 362 |
+
# though
|
| 363 |
+
iso_week = week_of_year = None
|
| 364 |
+
week_of_year_start = None
|
| 365 |
+
# weekday and julian defaulted to None so as to signal need to calculate
|
| 366 |
+
# values
|
| 367 |
+
weekday = julian = None
|
| 368 |
+
found_dict = found.groupdict()
|
| 369 |
+
for group_key in found_dict.keys():
|
| 370 |
+
# Directives not explicitly handled below:
|
| 371 |
+
# c, x, X
|
| 372 |
+
# handled by making out of other directives
|
| 373 |
+
# U, W
|
| 374 |
+
# worthless without day of the week
|
| 375 |
+
if group_key == 'y':
|
| 376 |
+
year = int(found_dict['y'])
|
| 377 |
+
# Open Group specification for strptime() states that a %y
|
| 378 |
+
#value in the range of [00, 68] is in the century 2000, while
|
| 379 |
+
#[69,99] is in the century 1900
|
| 380 |
+
if year <= 68:
|
| 381 |
+
year += 2000
|
| 382 |
+
else:
|
| 383 |
+
year += 1900
|
| 384 |
+
elif group_key == 'Y':
|
| 385 |
+
year = int(found_dict['Y'])
|
| 386 |
+
elif group_key == 'G':
|
| 387 |
+
iso_year = int(found_dict['G'])
|
| 388 |
+
elif group_key == 'm':
|
| 389 |
+
month = int(found_dict['m'])
|
| 390 |
+
elif group_key == 'B':
|
| 391 |
+
month = locale_time.f_month.index(found_dict['B'].lower())
|
| 392 |
+
elif group_key == 'b':
|
| 393 |
+
month = locale_time.a_month.index(found_dict['b'].lower())
|
| 394 |
+
elif group_key == 'd':
|
| 395 |
+
day = int(found_dict['d'])
|
| 396 |
+
elif group_key == 'H':
|
| 397 |
+
hour = int(found_dict['H'])
|
| 398 |
+
elif group_key == 'I':
|
| 399 |
+
hour = int(found_dict['I'])
|
| 400 |
+
ampm = found_dict.get('p', '').lower()
|
| 401 |
+
# If there was no AM/PM indicator, we'll treat this like AM
|
| 402 |
+
if ampm in ('', locale_time.am_pm[0]):
|
| 403 |
+
# We're in AM so the hour is correct unless we're
|
| 404 |
+
# looking at 12 midnight.
|
| 405 |
+
# 12 midnight == 12 AM == hour 0
|
| 406 |
+
if hour == 12:
|
| 407 |
+
hour = 0
|
| 408 |
+
elif ampm == locale_time.am_pm[1]:
|
| 409 |
+
# We're in PM so we need to add 12 to the hour unless
|
| 410 |
+
# we're looking at 12 noon.
|
| 411 |
+
# 12 noon == 12 PM == hour 12
|
| 412 |
+
if hour != 12:
|
| 413 |
+
hour += 12
|
| 414 |
+
elif group_key == 'M':
|
| 415 |
+
minute = int(found_dict['M'])
|
| 416 |
+
elif group_key == 'S':
|
| 417 |
+
second = int(found_dict['S'])
|
| 418 |
+
elif group_key == 'f':
|
| 419 |
+
s = found_dict['f']
|
| 420 |
+
# Pad to always return microseconds.
|
| 421 |
+
s += "0" * (6 - len(s))
|
| 422 |
+
fraction = int(s)
|
| 423 |
+
elif group_key == 'A':
|
| 424 |
+
weekday = locale_time.f_weekday.index(found_dict['A'].lower())
|
| 425 |
+
elif group_key == 'a':
|
| 426 |
+
weekday = locale_time.a_weekday.index(found_dict['a'].lower())
|
| 427 |
+
elif group_key == 'w':
|
| 428 |
+
weekday = int(found_dict['w'])
|
| 429 |
+
if weekday == 0:
|
| 430 |
+
weekday = 6
|
| 431 |
+
else:
|
| 432 |
+
weekday -= 1
|
| 433 |
+
elif group_key == 'u':
|
| 434 |
+
weekday = int(found_dict['u'])
|
| 435 |
+
weekday -= 1
|
| 436 |
+
elif group_key == 'j':
|
| 437 |
+
julian = int(found_dict['j'])
|
| 438 |
+
elif group_key in ('U', 'W'):
|
| 439 |
+
week_of_year = int(found_dict[group_key])
|
| 440 |
+
if group_key == 'U':
|
| 441 |
+
# U starts week on Sunday.
|
| 442 |
+
week_of_year_start = 6
|
| 443 |
+
else:
|
| 444 |
+
# W starts week on Monday.
|
| 445 |
+
week_of_year_start = 0
|
| 446 |
+
elif group_key == 'V':
|
| 447 |
+
iso_week = int(found_dict['V'])
|
| 448 |
+
elif group_key == 'z':
|
| 449 |
+
z = found_dict['z']
|
| 450 |
+
if z == 'Z':
|
| 451 |
+
gmtoff = 0
|
| 452 |
+
else:
|
| 453 |
+
if z[3] == ':':
|
| 454 |
+
z = z[:3] + z[4:]
|
| 455 |
+
if len(z) > 5:
|
| 456 |
+
if z[5] != ':':
|
| 457 |
+
msg = f"Inconsistent use of : in {found_dict['z']}"
|
| 458 |
+
raise ValueError(msg)
|
| 459 |
+
z = z[:5] + z[6:]
|
| 460 |
+
hours = int(z[1:3])
|
| 461 |
+
minutes = int(z[3:5])
|
| 462 |
+
seconds = int(z[5:7] or 0)
|
| 463 |
+
gmtoff = (hours * 60 * 60) + (minutes * 60) + seconds
|
| 464 |
+
gmtoff_remainder = z[8:]
|
| 465 |
+
# Pad to always return microseconds.
|
| 466 |
+
gmtoff_remainder_padding = "0" * (6 - len(gmtoff_remainder))
|
| 467 |
+
gmtoff_fraction = int(gmtoff_remainder + gmtoff_remainder_padding)
|
| 468 |
+
if z.startswith("-"):
|
| 469 |
+
gmtoff = -gmtoff
|
| 470 |
+
gmtoff_fraction = -gmtoff_fraction
|
| 471 |
+
elif group_key == 'Z':
|
| 472 |
+
# Since -1 is default value only need to worry about setting tz if
|
| 473 |
+
# it can be something other than -1.
|
| 474 |
+
found_zone = found_dict['Z'].lower()
|
| 475 |
+
for value, tz_values in enumerate(locale_time.timezone):
|
| 476 |
+
if found_zone in tz_values:
|
| 477 |
+
# Deal with bad locale setup where timezone names are the
|
| 478 |
+
# same and yet time.daylight is true; too ambiguous to
|
| 479 |
+
# be able to tell what timezone has daylight savings
|
| 480 |
+
if (time.tzname[0] == time.tzname[1] and
|
| 481 |
+
time.daylight and found_zone not in ("utc", "gmt")):
|
| 482 |
+
break
|
| 483 |
+
else:
|
| 484 |
+
tz = value
|
| 485 |
+
break
|
| 486 |
+
# Deal with the cases where ambiguities arize
|
| 487 |
+
# don't assume default values for ISO week/year
|
| 488 |
+
if year is None and iso_year is not None:
|
| 489 |
+
if iso_week is None or weekday is None:
|
| 490 |
+
raise ValueError("ISO year directive '%G' must be used with "
|
| 491 |
+
"the ISO week directive '%V' and a weekday "
|
| 492 |
+
"directive ('%A', '%a', '%w', or '%u').")
|
| 493 |
+
if julian is not None:
|
| 494 |
+
raise ValueError("Day of the year directive '%j' is not "
|
| 495 |
+
"compatible with ISO year directive '%G'. "
|
| 496 |
+
"Use '%Y' instead.")
|
| 497 |
+
elif week_of_year is None and iso_week is not None:
|
| 498 |
+
if weekday is None:
|
| 499 |
+
raise ValueError("ISO week directive '%V' must be used with "
|
| 500 |
+
"the ISO year directive '%G' and a weekday "
|
| 501 |
+
"directive ('%A', '%a', '%w', or '%u').")
|
| 502 |
+
else:
|
| 503 |
+
raise ValueError("ISO week directive '%V' is incompatible with "
|
| 504 |
+
"the year directive '%Y'. Use the ISO year '%G' "
|
| 505 |
+
"instead.")
|
| 506 |
+
|
| 507 |
+
leap_year_fix = False
|
| 508 |
+
if year is None and month == 2 and day == 29:
|
| 509 |
+
year = 1904 # 1904 is first leap year of 20th century
|
| 510 |
+
leap_year_fix = True
|
| 511 |
+
elif year is None:
|
| 512 |
+
year = 1900
|
| 513 |
+
|
| 514 |
+
|
| 515 |
+
# If we know the week of the year and what day of that week, we can figure
|
| 516 |
+
# out the Julian day of the year.
|
| 517 |
+
if julian is None and weekday is not None:
|
| 518 |
+
if week_of_year is not None:
|
| 519 |
+
week_starts_Mon = True if week_of_year_start == 0 else False
|
| 520 |
+
julian = _calc_julian_from_U_or_W(year, week_of_year, weekday,
|
| 521 |
+
week_starts_Mon)
|
| 522 |
+
elif iso_year is not None and iso_week is not None:
|
| 523 |
+
year, julian = _calc_julian_from_V(iso_year, iso_week, weekday + 1)
|
| 524 |
+
if julian is not None and julian <= 0:
|
| 525 |
+
year -= 1
|
| 526 |
+
yday = 366 if calendar.isleap(year) else 365
|
| 527 |
+
julian += yday
|
| 528 |
+
|
| 529 |
+
if julian is None:
|
| 530 |
+
# Cannot pre-calculate datetime_date() since can change in Julian
|
| 531 |
+
# calculation and thus could have different value for the day of
|
| 532 |
+
# the week calculation.
|
| 533 |
+
# Need to add 1 to result since first day of the year is 1, not 0.
|
| 534 |
+
julian = datetime_date(year, month, day).toordinal() - \
|
| 535 |
+
datetime_date(year, 1, 1).toordinal() + 1
|
| 536 |
+
else: # Assume that if they bothered to include Julian day (or if it was
|
| 537 |
+
# calculated above with year/week/weekday) it will be accurate.
|
| 538 |
+
datetime_result = datetime_date.fromordinal(
|
| 539 |
+
(julian - 1) +
|
| 540 |
+
datetime_date(year, 1, 1).toordinal())
|
| 541 |
+
year = datetime_result.year
|
| 542 |
+
month = datetime_result.month
|
| 543 |
+
day = datetime_result.day
|
| 544 |
+
if weekday is None:
|
| 545 |
+
weekday = datetime_date(year, month, day).weekday()
|
| 546 |
+
# Add timezone info
|
| 547 |
+
tzname = found_dict.get("Z")
|
| 548 |
+
|
| 549 |
+
if leap_year_fix:
|
| 550 |
+
# the caller didn't supply a year but asked for Feb 29th. We couldn't
|
| 551 |
+
# use the default of 1900 for computations. We set it back to ensure
|
| 552 |
+
# that February 29th is smaller than March 1st.
|
| 553 |
+
year = 1900
|
| 554 |
+
|
| 555 |
+
return (year, month, day,
|
| 556 |
+
hour, minute, second,
|
| 557 |
+
weekday, julian, tz, tzname, gmtoff), fraction, gmtoff_fraction
|
| 558 |
+
|
| 559 |
+
def _strptime_time(data_string, format="%a %b %d %H:%M:%S %Y"):
|
| 560 |
+
"""Return a time struct based on the input string and the
|
| 561 |
+
format string."""
|
| 562 |
+
tt = _strptime(data_string, format)[0]
|
| 563 |
+
return time.struct_time(tt[:time._STRUCT_TM_ITEMS])
|
| 564 |
+
|
| 565 |
+
def _strptime_datetime(cls, data_string, format="%a %b %d %H:%M:%S %Y"):
|
| 566 |
+
"""Return a class cls instance based on the input string and the
|
| 567 |
+
format string."""
|
| 568 |
+
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
|
| 569 |
+
tzname, gmtoff = tt[-2:]
|
| 570 |
+
args = tt[:6] + (fraction,)
|
| 571 |
+
if gmtoff is not None:
|
| 572 |
+
tzdelta = datetime_timedelta(seconds=gmtoff, microseconds=gmtoff_fraction)
|
| 573 |
+
if tzname:
|
| 574 |
+
tz = datetime_timezone(tzdelta, tzname)
|
| 575 |
+
else:
|
| 576 |
+
tz = datetime_timezone(tzdelta)
|
| 577 |
+
args += (tz,)
|
| 578 |
+
|
| 579 |
+
return cls(*args)
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata__linux_x86_64-linux-gnu.py
ADDED
|
@@ -0,0 +1,692 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# system configuration generated and used by the sysconfig module
|
| 2 |
+
build_time_vars = {'ABIFLAGS': '',
|
| 3 |
+
'AC_APPLE_UNIVERSAL_BUILD': 0,
|
| 4 |
+
'AIX_GENUINE_CPLUSPLUS': 0,
|
| 5 |
+
'ANDROID_API_LEVEL': 0,
|
| 6 |
+
'AR': 'ar',
|
| 7 |
+
'ARFLAGS': 'rc',
|
| 8 |
+
'BASECFLAGS': '-Wsign-compare',
|
| 9 |
+
'BASECPPFLAGS': '',
|
| 10 |
+
'BASEMODLIBS': '',
|
| 11 |
+
'BINDIR': '/workspace/anaconda3/bin',
|
| 12 |
+
'BINLIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 13 |
+
'BLDLIBRARY': '-L. -lpython3.8',
|
| 14 |
+
'BLDSHARED': 'gcc -pthread -shared -B /workspace/anaconda3/compiler_compat '
|
| 15 |
+
'-L/workspace/anaconda3/lib '
|
| 16 |
+
'-Wl,-rpath=/workspace/anaconda3/lib -Wl,--no-as-needed '
|
| 17 |
+
'-Wl,--sysroot=/',
|
| 18 |
+
'BUILDEXE': '',
|
| 19 |
+
'BUILDPYTHON': 'python',
|
| 20 |
+
'BUILD_GNU_TYPE': 'x86_64-pc-linux-gnu',
|
| 21 |
+
'BYTESTR_DEPS': '\\',
|
| 22 |
+
'CC': 'gcc -pthread -B /workspace/anaconda3/compiler_compat -Wl,--sysroot=/',
|
| 23 |
+
'CCSHARED': '-fPIC',
|
| 24 |
+
'CFLAGS': '-Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes',
|
| 25 |
+
'CFLAGSFORSHARED': '-fPIC',
|
| 26 |
+
'CFLAGS_ALIASING': '',
|
| 27 |
+
'CFLAGS_NODIST': '',
|
| 28 |
+
'CONFIGFILES': 'configure configure.ac acconfig.h pyconfig.h.in '
|
| 29 |
+
'Makefile.pre.in',
|
| 30 |
+
'CONFIGURE_CFLAGS': '',
|
| 31 |
+
'CONFIGURE_CFLAGS_NODIST': '-std=c99 -Wextra -Wno-unused-parameter '
|
| 32 |
+
'-Wno-missing-field-initializers',
|
| 33 |
+
'CONFIGURE_CPPFLAGS': '-I/workspace/anaconda3/include',
|
| 34 |
+
'CONFIGURE_LDFLAGS': '-L/workspace/anaconda3/lib '
|
| 35 |
+
'-Wl,-rpath=/workspace/anaconda3/lib -Wl,--no-as-needed '
|
| 36 |
+
'-Wl,--sysroot=/',
|
| 37 |
+
'CONFIG_ARGS': "'--enable-shared' '--enable-ipv6' '--with-ensurepip=no' "
|
| 38 |
+
"'--prefix=/workspace/anaconda3' "
|
| 39 |
+
"'--with-tcltk-includes=-I/workspace/anaconda3/include' "
|
| 40 |
+
"'--with-tcltk-libs=-L/workspace/anaconda3/lib "
|
| 41 |
+
"-ltcl8.6 -ltk8.6' "
|
| 42 |
+
"'CPPFLAGS=-I/workspace/anaconda3/include' "
|
| 43 |
+
"'LDFLAGS=-L/workspace/anaconda3/lib "
|
| 44 |
+
"-Wl,-rpath=/workspace/anaconda3/lib -Wl,--no-as-needed -Wl,--sysroot=/' "
|
| 45 |
+
"'PKG_CONFIG_PATH=/workspace/anaconda3/lib/pkgconfig'",
|
| 46 |
+
'CONFINCLUDEDIR': '/workspace/anaconda3/include',
|
| 47 |
+
'CONFINCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 48 |
+
'COREPYTHONPATH': ':',
|
| 49 |
+
'COVERAGE_INFO': '/workspace/anaconda3/../work/Python-3.8.18/coverage.info',
|
| 50 |
+
'COVERAGE_REPORT': '/workspace/anaconda3/../work/Python-3.8.18/lcov-report',
|
| 51 |
+
'COVERAGE_REPORT_OPTIONS': '--no-branch-coverage --title "CPython lcov '
|
| 52 |
+
'report"',
|
| 53 |
+
'CPPFLAGS': '-I. -I./Include '
|
| 54 |
+
'-I/workspace/anaconda3/include',
|
| 55 |
+
'CXX': 'g++ -pthread -B /workspace/anaconda3/compiler_compat -Wl,--sysroot=/',
|
| 56 |
+
'DESTDIRS': '/workspace/anaconda3 '
|
| 57 |
+
'/workspace/anaconda3/lib '
|
| 58 |
+
'/workspace/anaconda3/lib/python3.8 '
|
| 59 |
+
'/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 60 |
+
'DESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 61 |
+
'DESTPATH': '',
|
| 62 |
+
'DESTSHARED': '/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 63 |
+
'DFLAGS': '',
|
| 64 |
+
'DIRMODE': 755,
|
| 65 |
+
'DIST': 'README ChangeLog configure configure.ac acconfig.h pyconfig.h.in '
|
| 66 |
+
'Makefile.pre.in Include Lib Misc Ext-dummy',
|
| 67 |
+
'DISTDIRS': 'Include Lib Misc Ext-dummy',
|
| 68 |
+
'DISTFILES': 'README ChangeLog configure configure.ac acconfig.h '
|
| 69 |
+
'pyconfig.h.in Makefile.pre.in',
|
| 70 |
+
'DLINCLDIR': '.',
|
| 71 |
+
'DLLLIBRARY': '',
|
| 72 |
+
'DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754': 0,
|
| 73 |
+
'DOUBLE_IS_BIG_ENDIAN_IEEE754': 0,
|
| 74 |
+
'DOUBLE_IS_LITTLE_ENDIAN_IEEE754': 1,
|
| 75 |
+
'DTRACE': '',
|
| 76 |
+
'DTRACE_DEPS': '\\',
|
| 77 |
+
'DTRACE_HEADERS': '',
|
| 78 |
+
'DTRACE_OBJS': '',
|
| 79 |
+
'DYNLOADFILE': 'dynload_shlib.o',
|
| 80 |
+
'ENABLE_IPV6': 1,
|
| 81 |
+
'ENSUREPIP': 'no',
|
| 82 |
+
'EXE': '',
|
| 83 |
+
'EXEMODE': 755,
|
| 84 |
+
'EXTRAMACHDEPPATH': '',
|
| 85 |
+
'EXTRATESTOPTS': '',
|
| 86 |
+
'EXTRA_CFLAGS': '',
|
| 87 |
+
'EXT_SUFFIX': '.cpython-38-x86_64-linux-gnu.so',
|
| 88 |
+
'FILEMODE': 644,
|
| 89 |
+
'FLOCK_NEEDS_LIBBSD': 0,
|
| 90 |
+
'GETPGRP_HAVE_ARG': 0,
|
| 91 |
+
'GETTIMEOFDAY_NO_TZ': 0,
|
| 92 |
+
'GITBRANCH': '',
|
| 93 |
+
'GITTAG': '',
|
| 94 |
+
'GITVERSION': '',
|
| 95 |
+
'GNULD': 'yes',
|
| 96 |
+
'HAVE_ACCEPT4': 0,
|
| 97 |
+
'HAVE_ACOSH': 1,
|
| 98 |
+
'HAVE_ADDRINFO': 1,
|
| 99 |
+
'HAVE_ALARM': 1,
|
| 100 |
+
'HAVE_ALIGNED_REQUIRED': 0,
|
| 101 |
+
'HAVE_ALLOCA_H': 1,
|
| 102 |
+
'HAVE_ALTZONE': 0,
|
| 103 |
+
'HAVE_ASINH': 1,
|
| 104 |
+
'HAVE_ASM_TYPES_H': 1,
|
| 105 |
+
'HAVE_ATANH': 1,
|
| 106 |
+
'HAVE_BIND_TEXTDOMAIN_CODESET': 1,
|
| 107 |
+
'HAVE_BLUETOOTH_BLUETOOTH_H': 0,
|
| 108 |
+
'HAVE_BLUETOOTH_H': 0,
|
| 109 |
+
'HAVE_BROKEN_MBSTOWCS': 0,
|
| 110 |
+
'HAVE_BROKEN_NICE': 0,
|
| 111 |
+
'HAVE_BROKEN_PIPE_BUF': 0,
|
| 112 |
+
'HAVE_BROKEN_POLL': 0,
|
| 113 |
+
'HAVE_BROKEN_POSIX_SEMAPHORES': 0,
|
| 114 |
+
'HAVE_BROKEN_PTHREAD_SIGMASK': 0,
|
| 115 |
+
'HAVE_BROKEN_SEM_GETVALUE': 0,
|
| 116 |
+
'HAVE_BROKEN_UNSETENV': 0,
|
| 117 |
+
'HAVE_BUILTIN_ATOMIC': 0,
|
| 118 |
+
'HAVE_CHFLAGS': 0,
|
| 119 |
+
'HAVE_CHOWN': 1,
|
| 120 |
+
'HAVE_CHROOT': 1,
|
| 121 |
+
'HAVE_CLOCK': 1,
|
| 122 |
+
'HAVE_CLOCK_GETRES': 1,
|
| 123 |
+
'HAVE_CLOCK_GETTIME': 1,
|
| 124 |
+
'HAVE_CLOCK_SETTIME': 1,
|
| 125 |
+
'HAVE_COMPUTED_GOTOS': 1,
|
| 126 |
+
'HAVE_CONFSTR': 1,
|
| 127 |
+
'HAVE_CONIO_H': 0,
|
| 128 |
+
'HAVE_COPYSIGN': 1,
|
| 129 |
+
'HAVE_CTERMID': 1,
|
| 130 |
+
'HAVE_CTERMID_R': 0,
|
| 131 |
+
'HAVE_CURSES_H': 1,
|
| 132 |
+
'HAVE_CURSES_IS_TERM_RESIZED': 1,
|
| 133 |
+
'HAVE_CURSES_RESIZETERM': 1,
|
| 134 |
+
'HAVE_CURSES_RESIZE_TERM': 1,
|
| 135 |
+
'HAVE_DECL_ISFINITE': 1,
|
| 136 |
+
'HAVE_DECL_ISINF': 1,
|
| 137 |
+
'HAVE_DECL_ISNAN': 1,
|
| 138 |
+
'HAVE_DECL_RTLD_DEEPBIND': 1,
|
| 139 |
+
'HAVE_DECL_RTLD_GLOBAL': 1,
|
| 140 |
+
'HAVE_DECL_RTLD_LAZY': 1,
|
| 141 |
+
'HAVE_DECL_RTLD_LOCAL': 1,
|
| 142 |
+
'HAVE_DECL_RTLD_NODELETE': 1,
|
| 143 |
+
'HAVE_DECL_RTLD_NOLOAD': 1,
|
| 144 |
+
'HAVE_DECL_RTLD_NOW': 1,
|
| 145 |
+
'HAVE_DECL_TZNAME': 0,
|
| 146 |
+
'HAVE_DEVICE_MACROS': 1,
|
| 147 |
+
'HAVE_DEV_PTC': 0,
|
| 148 |
+
'HAVE_DEV_PTMX': 1,
|
| 149 |
+
'HAVE_DIRECT_H': 0,
|
| 150 |
+
'HAVE_DIRENT_D_TYPE': 1,
|
| 151 |
+
'HAVE_DIRENT_H': 1,
|
| 152 |
+
'HAVE_DIRFD': 1,
|
| 153 |
+
'HAVE_DLFCN_H': 1,
|
| 154 |
+
'HAVE_DLOPEN': 1,
|
| 155 |
+
'HAVE_DUP2': 1,
|
| 156 |
+
'HAVE_DUP3': 0,
|
| 157 |
+
'HAVE_DYNAMIC_LOADING': 1,
|
| 158 |
+
'HAVE_ENDIAN_H': 1,
|
| 159 |
+
'HAVE_EPOLL': 1,
|
| 160 |
+
'HAVE_EPOLL_CREATE1': 0,
|
| 161 |
+
'HAVE_ERF': 1,
|
| 162 |
+
'HAVE_ERFC': 1,
|
| 163 |
+
'HAVE_ERRNO_H': 1,
|
| 164 |
+
'HAVE_EXECV': 1,
|
| 165 |
+
'HAVE_EXPM1': 1,
|
| 166 |
+
'HAVE_FACCESSAT': 1,
|
| 167 |
+
'HAVE_FCHDIR': 1,
|
| 168 |
+
'HAVE_FCHMOD': 1,
|
| 169 |
+
'HAVE_FCHMODAT': 1,
|
| 170 |
+
'HAVE_FCHOWN': 1,
|
| 171 |
+
'HAVE_FCHOWNAT': 1,
|
| 172 |
+
'HAVE_FCNTL_H': 1,
|
| 173 |
+
'HAVE_FDATASYNC': 1,
|
| 174 |
+
'HAVE_FDOPENDIR': 1,
|
| 175 |
+
'HAVE_FEXECVE': 1,
|
| 176 |
+
'HAVE_FINITE': 1,
|
| 177 |
+
'HAVE_FLOCK': 1,
|
| 178 |
+
'HAVE_FORK': 1,
|
| 179 |
+
'HAVE_FORKPTY': 1,
|
| 180 |
+
'HAVE_FPATHCONF': 1,
|
| 181 |
+
'HAVE_FSEEK64': 0,
|
| 182 |
+
'HAVE_FSEEKO': 1,
|
| 183 |
+
'HAVE_FSTATAT': 1,
|
| 184 |
+
'HAVE_FSTATVFS': 1,
|
| 185 |
+
'HAVE_FSYNC': 1,
|
| 186 |
+
'HAVE_FTELL64': 0,
|
| 187 |
+
'HAVE_FTELLO': 1,
|
| 188 |
+
'HAVE_FTIME': 1,
|
| 189 |
+
'HAVE_FTRUNCATE': 1,
|
| 190 |
+
'HAVE_FUTIMENS': 0,
|
| 191 |
+
'HAVE_FUTIMES': 1,
|
| 192 |
+
'HAVE_FUTIMESAT': 1,
|
| 193 |
+
'HAVE_GAI_STRERROR': 1,
|
| 194 |
+
'HAVE_GAMMA': 1,
|
| 195 |
+
'HAVE_GCC_ASM_FOR_MC68881': 0,
|
| 196 |
+
'HAVE_GCC_ASM_FOR_X64': 1,
|
| 197 |
+
'HAVE_GCC_ASM_FOR_X87': 1,
|
| 198 |
+
'HAVE_GCC_UINT128_T': 1,
|
| 199 |
+
'HAVE_GETADDRINFO': 1,
|
| 200 |
+
'HAVE_GETC_UNLOCKED': 1,
|
| 201 |
+
'HAVE_GETENTROPY': 0,
|
| 202 |
+
'HAVE_GETGROUPLIST': 1,
|
| 203 |
+
'HAVE_GETGROUPS': 1,
|
| 204 |
+
'HAVE_GETHOSTBYNAME': 0,
|
| 205 |
+
'HAVE_GETHOSTBYNAME_R': 1,
|
| 206 |
+
'HAVE_GETHOSTBYNAME_R_3_ARG': 0,
|
| 207 |
+
'HAVE_GETHOSTBYNAME_R_5_ARG': 0,
|
| 208 |
+
'HAVE_GETHOSTBYNAME_R_6_ARG': 1,
|
| 209 |
+
'HAVE_GETITIMER': 1,
|
| 210 |
+
'HAVE_GETLOADAVG': 1,
|
| 211 |
+
'HAVE_GETLOGIN': 1,
|
| 212 |
+
'HAVE_GETNAMEINFO': 1,
|
| 213 |
+
'HAVE_GETPAGESIZE': 1,
|
| 214 |
+
'HAVE_GETPEERNAME': 1,
|
| 215 |
+
'HAVE_GETPGID': 1,
|
| 216 |
+
'HAVE_GETPGRP': 1,
|
| 217 |
+
'HAVE_GETPID': 1,
|
| 218 |
+
'HAVE_GETPRIORITY': 1,
|
| 219 |
+
'HAVE_GETPWENT': 1,
|
| 220 |
+
'HAVE_GETRANDOM': 0,
|
| 221 |
+
'HAVE_GETRANDOM_SYSCALL': 0,
|
| 222 |
+
'HAVE_GETRESGID': 1,
|
| 223 |
+
'HAVE_GETRESUID': 1,
|
| 224 |
+
'HAVE_GETSID': 1,
|
| 225 |
+
'HAVE_GETSPENT': 1,
|
| 226 |
+
'HAVE_GETSPNAM': 1,
|
| 227 |
+
'HAVE_GETTIMEOFDAY': 1,
|
| 228 |
+
'HAVE_GETWD': 1,
|
| 229 |
+
'HAVE_GLIBC_MEMMOVE_BUG': 0,
|
| 230 |
+
'HAVE_GRP_H': 1,
|
| 231 |
+
'HAVE_HSTRERROR': 1,
|
| 232 |
+
'HAVE_HTOLE64': 0,
|
| 233 |
+
'HAVE_HYPOT': 1,
|
| 234 |
+
'HAVE_IEEEFP_H': 0,
|
| 235 |
+
'HAVE_IF_NAMEINDEX': 1,
|
| 236 |
+
'HAVE_INET_ATON': 1,
|
| 237 |
+
'HAVE_INET_PTON': 1,
|
| 238 |
+
'HAVE_INITGROUPS': 1,
|
| 239 |
+
'HAVE_INTTYPES_H': 1,
|
| 240 |
+
'HAVE_IO_H': 0,
|
| 241 |
+
'HAVE_IPA_PURE_CONST_BUG': 0,
|
| 242 |
+
'HAVE_KILL': 1,
|
| 243 |
+
'HAVE_KILLPG': 1,
|
| 244 |
+
'HAVE_KQUEUE': 0,
|
| 245 |
+
'HAVE_LANGINFO_H': 1,
|
| 246 |
+
'HAVE_LARGEFILE_SUPPORT': 0,
|
| 247 |
+
'HAVE_LCHFLAGS': 0,
|
| 248 |
+
'HAVE_LCHMOD': 0,
|
| 249 |
+
'HAVE_LCHOWN': 1,
|
| 250 |
+
'HAVE_LGAMMA': 1,
|
| 251 |
+
'HAVE_LIBDL': 1,
|
| 252 |
+
'HAVE_LIBDLD': 0,
|
| 253 |
+
'HAVE_LIBIEEE': 0,
|
| 254 |
+
'HAVE_LIBINTL_H': 1,
|
| 255 |
+
'HAVE_LIBREADLINE': 1,
|
| 256 |
+
'HAVE_LIBRESOLV': 0,
|
| 257 |
+
'HAVE_LIBSENDFILE': 0,
|
| 258 |
+
'HAVE_LIBUTIL_H': 0,
|
| 259 |
+
'HAVE_LINK': 1,
|
| 260 |
+
'HAVE_LINKAT': 1,
|
| 261 |
+
'HAVE_LINUX_CAN_BCM_H': 0,
|
| 262 |
+
'HAVE_LINUX_CAN_H': 0,
|
| 263 |
+
'HAVE_LINUX_CAN_RAW_FD_FRAMES': 0,
|
| 264 |
+
'HAVE_LINUX_CAN_RAW_H': 0,
|
| 265 |
+
'HAVE_LINUX_NETLINK_H': 1,
|
| 266 |
+
'HAVE_LINUX_RANDOM_H': 0,
|
| 267 |
+
'HAVE_LINUX_TIPC_H': 1,
|
| 268 |
+
'HAVE_LOCKF': 1,
|
| 269 |
+
'HAVE_LOG1P': 1,
|
| 270 |
+
'HAVE_LOG2': 1,
|
| 271 |
+
'HAVE_LONG_DOUBLE': 1,
|
| 272 |
+
'HAVE_LSTAT': 1,
|
| 273 |
+
'HAVE_LUTIMES': 0,
|
| 274 |
+
'HAVE_MAKEDEV': 1,
|
| 275 |
+
'HAVE_MBRTOWC': 1,
|
| 276 |
+
'HAVE_MEMMOVE': 1,
|
| 277 |
+
'HAVE_MEMORY_H': 1,
|
| 278 |
+
'HAVE_MEMRCHR': 1,
|
| 279 |
+
'HAVE_MKDIRAT': 1,
|
| 280 |
+
'HAVE_MKFIFO': 1,
|
| 281 |
+
'HAVE_MKFIFOAT': 1,
|
| 282 |
+
'HAVE_MKNOD': 1,
|
| 283 |
+
'HAVE_MKNODAT': 1,
|
| 284 |
+
'HAVE_MKTIME': 1,
|
| 285 |
+
'HAVE_MMAP': 1,
|
| 286 |
+
'HAVE_MREMAP': 1,
|
| 287 |
+
'HAVE_NCURSES_H': 1,
|
| 288 |
+
'HAVE_NDIR_H': 0,
|
| 289 |
+
'HAVE_NETPACKET_PACKET_H': 1,
|
| 290 |
+
'HAVE_NET_IF_H': 1,
|
| 291 |
+
'HAVE_NICE': 1,
|
| 292 |
+
'HAVE_OPENAT': 1,
|
| 293 |
+
'HAVE_OPENPTY': 1,
|
| 294 |
+
'HAVE_PATHCONF': 1,
|
| 295 |
+
'HAVE_PAUSE': 1,
|
| 296 |
+
'HAVE_PIPE2': 0,
|
| 297 |
+
'HAVE_PLOCK': 0,
|
| 298 |
+
'HAVE_POLL': 1,
|
| 299 |
+
'HAVE_POLL_H': 1,
|
| 300 |
+
'HAVE_POSIX_FADVISE': 1,
|
| 301 |
+
'HAVE_POSIX_FALLOCATE': 1,
|
| 302 |
+
'HAVE_PREAD': 1,
|
| 303 |
+
'HAVE_PRLIMIT': 0,
|
| 304 |
+
'HAVE_PROCESS_H': 0,
|
| 305 |
+
'HAVE_PROTOTYPES': 1,
|
| 306 |
+
'HAVE_PTHREAD_ATFORK': 1,
|
| 307 |
+
'HAVE_PTHREAD_DESTRUCTOR': 0,
|
| 308 |
+
'HAVE_PTHREAD_H': 1,
|
| 309 |
+
'HAVE_PTHREAD_INIT': 0,
|
| 310 |
+
'HAVE_PTHREAD_KILL': 1,
|
| 311 |
+
'HAVE_PTHREAD_SIGMASK': 1,
|
| 312 |
+
'HAVE_PTY_H': 1,
|
| 313 |
+
'HAVE_PUTENV': 1,
|
| 314 |
+
'HAVE_PWRITE': 1,
|
| 315 |
+
'HAVE_READLINK': 1,
|
| 316 |
+
'HAVE_READLINKAT': 1,
|
| 317 |
+
'HAVE_READV': 1,
|
| 318 |
+
'HAVE_REALPATH': 1,
|
| 319 |
+
'HAVE_RENAMEAT': 1,
|
| 320 |
+
'HAVE_RL_APPEND_HISTORY': 1,
|
| 321 |
+
'HAVE_RL_CALLBACK': 1,
|
| 322 |
+
'HAVE_RL_CATCH_SIGNAL': 1,
|
| 323 |
+
'HAVE_RL_COMPLETION_APPEND_CHARACTER': 1,
|
| 324 |
+
'HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK': 1,
|
| 325 |
+
'HAVE_RL_COMPLETION_MATCHES': 1,
|
| 326 |
+
'HAVE_RL_COMPLETION_SUPPRESS_APPEND': 1,
|
| 327 |
+
'HAVE_RL_PRE_INPUT_HOOK': 1,
|
| 328 |
+
'HAVE_RL_RESIZE_TERMINAL': 1,
|
| 329 |
+
'HAVE_ROUND': 1,
|
| 330 |
+
'HAVE_SCHED_GET_PRIORITY_MAX': 1,
|
| 331 |
+
'HAVE_SCHED_H': 1,
|
| 332 |
+
'HAVE_SCHED_RR_GET_INTERVAL': 1,
|
| 333 |
+
'HAVE_SCHED_SETAFFINITY': 1,
|
| 334 |
+
'HAVE_SCHED_SETPARAM': 1,
|
| 335 |
+
'HAVE_SCHED_SETSCHEDULER': 1,
|
| 336 |
+
'HAVE_SELECT': 1,
|
| 337 |
+
'HAVE_SEM_GETVALUE': 1,
|
| 338 |
+
'HAVE_SEM_OPEN': 1,
|
| 339 |
+
'HAVE_SEM_TIMEDWAIT': 1,
|
| 340 |
+
'HAVE_SEM_UNLINK': 1,
|
| 341 |
+
'HAVE_SENDFILE': 1,
|
| 342 |
+
'HAVE_SETEGID': 1,
|
| 343 |
+
'HAVE_SETEUID': 1,
|
| 344 |
+
'HAVE_SETGID': 1,
|
| 345 |
+
'HAVE_SETGROUPS': 1,
|
| 346 |
+
'HAVE_SETHOSTNAME': 1,
|
| 347 |
+
'HAVE_SETITIMER': 1,
|
| 348 |
+
'HAVE_SETLOCALE': 1,
|
| 349 |
+
'HAVE_SETPGID': 1,
|
| 350 |
+
'HAVE_SETPGRP': 1,
|
| 351 |
+
'HAVE_SETPRIORITY': 1,
|
| 352 |
+
'HAVE_SETREGID': 1,
|
| 353 |
+
'HAVE_SETRESGID': 1,
|
| 354 |
+
'HAVE_SETRESUID': 1,
|
| 355 |
+
'HAVE_SETREUID': 1,
|
| 356 |
+
'HAVE_SETSID': 1,
|
| 357 |
+
'HAVE_SETUID': 1,
|
| 358 |
+
'HAVE_SETVBUF': 1,
|
| 359 |
+
'HAVE_SHADOW_H': 1,
|
| 360 |
+
'HAVE_SIGACTION': 1,
|
| 361 |
+
'HAVE_SIGALTSTACK': 1,
|
| 362 |
+
'HAVE_SIGINTERRUPT': 1,
|
| 363 |
+
'HAVE_SIGNAL_H': 1,
|
| 364 |
+
'HAVE_SIGPENDING': 1,
|
| 365 |
+
'HAVE_SIGRELSE': 1,
|
| 366 |
+
'HAVE_SIGTIMEDWAIT': 1,
|
| 367 |
+
'HAVE_SIGWAIT': 1,
|
| 368 |
+
'HAVE_SIGWAITINFO': 1,
|
| 369 |
+
'HAVE_SNPRINTF': 1,
|
| 370 |
+
'HAVE_SOCKADDR_ALG': 0,
|
| 371 |
+
'HAVE_SOCKADDR_SA_LEN': 0,
|
| 372 |
+
'HAVE_SOCKADDR_STORAGE': 1,
|
| 373 |
+
'HAVE_SOCKETPAIR': 1,
|
| 374 |
+
'HAVE_SPAWN_H': 1,
|
| 375 |
+
'HAVE_SSIZE_T': 1,
|
| 376 |
+
'HAVE_STATVFS': 1,
|
| 377 |
+
'HAVE_STAT_TV_NSEC': 1,
|
| 378 |
+
'HAVE_STAT_TV_NSEC2': 0,
|
| 379 |
+
'HAVE_STDARG_PROTOTYPES': 1,
|
| 380 |
+
'HAVE_STDINT_H': 1,
|
| 381 |
+
'HAVE_STDLIB_H': 1,
|
| 382 |
+
'HAVE_STD_ATOMIC': 0,
|
| 383 |
+
'HAVE_STRDUP': 1,
|
| 384 |
+
'HAVE_STRFTIME': 1,
|
| 385 |
+
'HAVE_STRINGS_H': 1,
|
| 386 |
+
'HAVE_STRING_H': 1,
|
| 387 |
+
'HAVE_STRLCPY': 0,
|
| 388 |
+
'HAVE_STROPTS_H': 1,
|
| 389 |
+
'HAVE_STRUCT_PASSWD_PW_GECOS': 1,
|
| 390 |
+
'HAVE_STRUCT_PASSWD_PW_PASSWD': 1,
|
| 391 |
+
'HAVE_STRUCT_STAT_ST_BIRTHTIME': 0,
|
| 392 |
+
'HAVE_STRUCT_STAT_ST_BLKSIZE': 1,
|
| 393 |
+
'HAVE_STRUCT_STAT_ST_BLOCKS': 1,
|
| 394 |
+
'HAVE_STRUCT_STAT_ST_FLAGS': 0,
|
| 395 |
+
'HAVE_STRUCT_STAT_ST_GEN': 0,
|
| 396 |
+
'HAVE_STRUCT_STAT_ST_RDEV': 1,
|
| 397 |
+
'HAVE_STRUCT_TM_TM_ZONE': 1,
|
| 398 |
+
'HAVE_SYMLINK': 1,
|
| 399 |
+
'HAVE_SYMLINKAT': 1,
|
| 400 |
+
'HAVE_SYNC': 1,
|
| 401 |
+
'HAVE_SYSCONF': 1,
|
| 402 |
+
'HAVE_SYSEXITS_H': 1,
|
| 403 |
+
'HAVE_SYS_AUDIOIO_H': 0,
|
| 404 |
+
'HAVE_SYS_BSDTTY_H': 0,
|
| 405 |
+
'HAVE_SYS_DEVPOLL_H': 0,
|
| 406 |
+
'HAVE_SYS_DIR_H': 0,
|
| 407 |
+
'HAVE_SYS_ENDIAN_H': 0,
|
| 408 |
+
'HAVE_SYS_EPOLL_H': 1,
|
| 409 |
+
'HAVE_SYS_EVENT_H': 0,
|
| 410 |
+
'HAVE_SYS_FILE_H': 1,
|
| 411 |
+
'HAVE_SYS_IOCTL_H': 1,
|
| 412 |
+
'HAVE_SYS_KERN_CONTROL_H': 0,
|
| 413 |
+
'HAVE_SYS_LOADAVG_H': 0,
|
| 414 |
+
'HAVE_SYS_LOCK_H': 0,
|
| 415 |
+
'HAVE_SYS_MKDEV_H': 0,
|
| 416 |
+
'HAVE_SYS_MODEM_H': 0,
|
| 417 |
+
'HAVE_SYS_NDIR_H': 0,
|
| 418 |
+
'HAVE_SYS_PARAM_H': 1,
|
| 419 |
+
'HAVE_SYS_POLL_H': 1,
|
| 420 |
+
'HAVE_SYS_RANDOM_H': 0,
|
| 421 |
+
'HAVE_SYS_RESOURCE_H': 1,
|
| 422 |
+
'HAVE_SYS_SELECT_H': 1,
|
| 423 |
+
'HAVE_SYS_SENDFILE_H': 1,
|
| 424 |
+
'HAVE_SYS_SOCKET_H': 1,
|
| 425 |
+
'HAVE_SYS_STATVFS_H': 1,
|
| 426 |
+
'HAVE_SYS_STAT_H': 1,
|
| 427 |
+
'HAVE_SYS_SYSCALL_H': 1,
|
| 428 |
+
'HAVE_SYS_SYS_DOMAIN_H': 0,
|
| 429 |
+
'HAVE_SYS_TERMIO_H': 0,
|
| 430 |
+
'HAVE_SYS_TIMES_H': 1,
|
| 431 |
+
'HAVE_SYS_TIME_H': 1,
|
| 432 |
+
'HAVE_SYS_TYPES_H': 1,
|
| 433 |
+
'HAVE_SYS_UIO_H': 1,
|
| 434 |
+
'HAVE_SYS_UN_H': 1,
|
| 435 |
+
'HAVE_SYS_UTSNAME_H': 1,
|
| 436 |
+
'HAVE_SYS_WAIT_H': 1,
|
| 437 |
+
'HAVE_SYS_XATTR_H': 1,
|
| 438 |
+
'HAVE_TCGETPGRP': 1,
|
| 439 |
+
'HAVE_TCSETPGRP': 1,
|
| 440 |
+
'HAVE_TEMPNAM': 1,
|
| 441 |
+
'HAVE_TERMIOS_H': 1,
|
| 442 |
+
'HAVE_TERM_H': 1,
|
| 443 |
+
'HAVE_TGAMMA': 1,
|
| 444 |
+
'HAVE_TIMEGM': 1,
|
| 445 |
+
'HAVE_TIMES': 1,
|
| 446 |
+
'HAVE_TMPFILE': 1,
|
| 447 |
+
'HAVE_TMPNAM': 1,
|
| 448 |
+
'HAVE_TMPNAM_R': 1,
|
| 449 |
+
'HAVE_TM_ZONE': 1,
|
| 450 |
+
'HAVE_TRUNCATE': 1,
|
| 451 |
+
'HAVE_TZNAME': 0,
|
| 452 |
+
'HAVE_UCS4_TCL': 0,
|
| 453 |
+
'HAVE_UNAME': 1,
|
| 454 |
+
'HAVE_UNISTD_H': 1,
|
| 455 |
+
'HAVE_UNLINKAT': 1,
|
| 456 |
+
'HAVE_UNSETENV': 1,
|
| 457 |
+
'HAVE_USABLE_WCHAR_T': 0,
|
| 458 |
+
'HAVE_UTIL_H': 0,
|
| 459 |
+
'HAVE_UTIMENSAT': 0,
|
| 460 |
+
'HAVE_UTIMES': 1,
|
| 461 |
+
'HAVE_UTIME_H': 1,
|
| 462 |
+
'HAVE_WAIT3': 1,
|
| 463 |
+
'HAVE_WAIT4': 1,
|
| 464 |
+
'HAVE_WAITID': 1,
|
| 465 |
+
'HAVE_WAITPID': 1,
|
| 466 |
+
'HAVE_WCHAR_H': 1,
|
| 467 |
+
'HAVE_WCSCOLL': 1,
|
| 468 |
+
'HAVE_WCSFTIME': 1,
|
| 469 |
+
'HAVE_WCSXFRM': 1,
|
| 470 |
+
'HAVE_WMEMCMP': 1,
|
| 471 |
+
'HAVE_WORKING_TZSET': 1,
|
| 472 |
+
'HAVE_WRITEV': 1,
|
| 473 |
+
'HAVE_ZLIB_COPY': 1,
|
| 474 |
+
'HAVE__GETPTY': 0,
|
| 475 |
+
'HOST_GNU_TYPE': 'x86_64-pc-linux-gnu',
|
| 476 |
+
'INCLDIRSTOMAKE': '/workspace/anaconda3/include '
|
| 477 |
+
'/workspace/anaconda3/include '
|
| 478 |
+
'/workspace/anaconda3/include/python3.8 '
|
| 479 |
+
'/workspace/anaconda3/include/python3.8',
|
| 480 |
+
'INCLUDEDIR': '/workspace/anaconda3/include',
|
| 481 |
+
'INCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 482 |
+
'INSTALL': '/usr/bin/install -c',
|
| 483 |
+
'INSTALL_DATA': '/usr/bin/install -c -m 644',
|
| 484 |
+
'INSTALL_PROGRAM': '/usr/bin/install -c',
|
| 485 |
+
'INSTALL_SCRIPT': '/usr/bin/install -c',
|
| 486 |
+
'INSTALL_SHARED': '/usr/bin/install -c -m 555',
|
| 487 |
+
'INSTSONAME': 'libpython3.8.so.1.0',
|
| 488 |
+
'IO_H': 'Modules/_io/_iomodule.h',
|
| 489 |
+
'IO_OBJS': '\\',
|
| 490 |
+
'LDCXXSHARED': 'g++ -pthread -shared -B /workspace/anaconda3/compiler_compat '
|
| 491 |
+
'-L/workspace/anaconda3/lib '
|
| 492 |
+
'-Wl,-rpath=/workspace/anaconda3/lib -Wl,--no-as-needed '
|
| 493 |
+
'-Wl,--sysroot=/',
|
| 494 |
+
'LDFLAGS': '-L/workspace/anaconda3/lib '
|
| 495 |
+
'-Wl,-rpath=/workspace/anaconda3/lib -Wl,--no-as-needed '
|
| 496 |
+
'-Wl,--sysroot=/',
|
| 497 |
+
'LDLAST': '',
|
| 498 |
+
'LDLIBRARY': 'libpython3.8.so',
|
| 499 |
+
'LDLIBRARYDIR': '',
|
| 500 |
+
'LDSHARED': 'gcc -pthread -shared -B /workspace/anaconda3/compiler_compat '
|
| 501 |
+
'-L/workspace/anaconda3/lib '
|
| 502 |
+
'-Wl,-rpath=/workspace/anaconda3/lib -Wl,--no-as-needed '
|
| 503 |
+
'-Wl,--sysroot=/',
|
| 504 |
+
'LDVERSION': '3.8',
|
| 505 |
+
'LIBC': '',
|
| 506 |
+
'LIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 507 |
+
'LIBDIR': '/workspace/anaconda3/lib',
|
| 508 |
+
'LIBFFI_INCLUDEDIR': '',
|
| 509 |
+
'LIBM': '-lm',
|
| 510 |
+
'LIBOBJDIR': 'Python/',
|
| 511 |
+
'LIBOBJS': '',
|
| 512 |
+
'LIBPC': '/workspace/anaconda3/lib/pkgconfig',
|
| 513 |
+
'LIBPL': '/workspace/anaconda3/lib/python3.8/config-3.8-x86_64-linux-gnu',
|
| 514 |
+
'LIBRARY': 'libpython3.8.a',
|
| 515 |
+
'LIBRARY_OBJS': '\\',
|
| 516 |
+
'LIBRARY_OBJS_OMIT_FROZEN': '\\',
|
| 517 |
+
'LIBS': '-lpthread -ldl -lutil -lrt',
|
| 518 |
+
'LIBSUBDIRS': 'tkinter tkinter/test tkinter/test/test_tkinter \\',
|
| 519 |
+
'LINKCC': 'gcc -pthread -B /workspace/anaconda3/compiler_compat -Wl,--sysroot/',
|
| 520 |
+
'LINKFORSHARED': '-Xlinker -export-dynamic',
|
| 521 |
+
'LIPO_32BIT_FLAGS': '',
|
| 522 |
+
'LLVM_PROF_ERR': 'no',
|
| 523 |
+
'LLVM_PROF_FILE': '',
|
| 524 |
+
'LLVM_PROF_MERGER': 'true',
|
| 525 |
+
'LN': 'ln',
|
| 526 |
+
'LOCALMODLIBS': '',
|
| 527 |
+
'LOG1P_DROPS_ZERO_SIGN': 0,
|
| 528 |
+
'MACHDEP': 'linux',
|
| 529 |
+
'MACHDEPPATH': ':',
|
| 530 |
+
'MACHDEP_OBJS': '',
|
| 531 |
+
'MACHDESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 532 |
+
'MACOSX_DEPLOYMENT_TARGET': '',
|
| 533 |
+
'MAINCC': 'gcc -pthread -B /workspace/anaconda3/compiler_compat -Wl,--sysroot=/',
|
| 534 |
+
'MAJOR_IN_MKDEV': 0,
|
| 535 |
+
'MAJOR_IN_SYSMACROS': 0,
|
| 536 |
+
'MAKESETUP': './Modules/makesetup',
|
| 537 |
+
'MANDIR': '/workspace/anaconda3/share/man',
|
| 538 |
+
'MKDIR_P': '/bin/mkdir -p',
|
| 539 |
+
'MODLIBS': '',
|
| 540 |
+
'MODNAMES': '_thread posix errno pwd _sre _codecs _weakref _functools '
|
| 541 |
+
'_operator _collections itertools atexit _signal _stat time '
|
| 542 |
+
'_locale _io zipimport faulthandler _tracemalloc _symtable '
|
| 543 |
+
'xxsubtype',
|
| 544 |
+
'MODOBJS': 'Modules/_threadmodule.o Modules/posixmodule.o '
|
| 545 |
+
'Modules/errnomodule.o Modules/pwdmodule.o Modules/_sre.o '
|
| 546 |
+
'Modules/_codecsmodule.o Modules/_weakref.o '
|
| 547 |
+
'Modules/_functoolsmodule.o Modules/_operator.o '
|
| 548 |
+
'Modules/_collectionsmodule.o Modules/itertoolsmodule.o '
|
| 549 |
+
'Modules/atexitmodule.o Modules/signalmodule.o Modules/_stat.o '
|
| 550 |
+
'Modules/timemodule.o Modules/_localemodule.o '
|
| 551 |
+
'Modules/_iomodule.o Modules/iobase.o Modules/fileio.o '
|
| 552 |
+
'Modules/bytesio.o Modules/bufferedio.o Modules/textio.o '
|
| 553 |
+
'Modules/stringio.o Modules/zipimport.o Modules/faulthandler.o '
|
| 554 |
+
'Modules/_tracemalloc.o Modules/hashtable.o '
|
| 555 |
+
'Modules/symtablemodule.o Modules/xxsubtype.o',
|
| 556 |
+
'MODULE_OBJS': '\\',
|
| 557 |
+
'MULTIARCH': 'x86_64-linux-gnu',
|
| 558 |
+
'MULTIARCH_CPPFLAGS': '-DMULTIARCH=\\"x86_64-linux-gnu\\"',
|
| 559 |
+
'MVWDELCH_IS_EXPRESSION': 1,
|
| 560 |
+
'NO_AS_NEEDED': '-Wl,--no-as-needed',
|
| 561 |
+
'OBJECT_OBJS': '\\',
|
| 562 |
+
'OPT': '-DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes',
|
| 563 |
+
'OTHER_LIBTOOL_OPT': '',
|
| 564 |
+
'PACKAGE_BUGREPORT': 0,
|
| 565 |
+
'PACKAGE_NAME': 0,
|
| 566 |
+
'PACKAGE_STRING': 0,
|
| 567 |
+
'PACKAGE_TARNAME': 0,
|
| 568 |
+
'PACKAGE_URL': 0,
|
| 569 |
+
'PACKAGE_VERSION': 0,
|
| 570 |
+
'PARSER_HEADERS': '\\',
|
| 571 |
+
'PARSER_OBJS': '\\ Parser/myreadline.o Parser/parsetok.o Parser/tokenizer.o',
|
| 572 |
+
'PGEN': 'Parser/pgen',
|
| 573 |
+
'PGENOBJS': '\\ \\',
|
| 574 |
+
'PGOBJS': '\\',
|
| 575 |
+
'PGO_PROF_GEN_FLAG': '-fprofile-generate',
|
| 576 |
+
'PGO_PROF_USE_FLAG': '-fprofile-use -fprofile-correction',
|
| 577 |
+
'PLATDIR': '',
|
| 578 |
+
'POBJS': '\\',
|
| 579 |
+
'POSIX_SEMAPHORES_NOT_ENABLED': 0,
|
| 580 |
+
'PROFILE_TASK': '-m test.regrtest --pgo',
|
| 581 |
+
'PTHREAD_SYSTEM_SCHED_SUPPORTED': 1,
|
| 582 |
+
'PURIFY': '',
|
| 583 |
+
'PY3LIBRARY': 'libpython3.so',
|
| 584 |
+
'PYLONG_BITS_IN_DIGIT': 0,
|
| 585 |
+
'PYTHON': 'python',
|
| 586 |
+
'PYTHONFRAMEWORK': '',
|
| 587 |
+
'PYTHONFRAMEWORKDIR': 'no-framework',
|
| 588 |
+
'PYTHONFRAMEWORKINSTALLDIR': '',
|
| 589 |
+
'PYTHONFRAMEWORKPREFIX': '',
|
| 590 |
+
'PYTHONPATH': ':',
|
| 591 |
+
'PYTHON_FOR_BUILD': './python -E',
|
| 592 |
+
'PYTHON_FOR_REGEN': 'python',
|
| 593 |
+
'PYTHON_HEADERS': '\\',
|
| 594 |
+
'PYTHON_OBJS': '\\',
|
| 595 |
+
'PY_CFLAGS': '-Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall '
|
| 596 |
+
'-Wstrict-prototypes',
|
| 597 |
+
'PY_CFLAGS_NODIST': '-std=c99 -Wextra -Wno-unused-parameter '
|
| 598 |
+
'-Wno-missing-field-initializers',
|
| 599 |
+
'PY_CORE_CFLAGS': '-Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall '
|
| 600 |
+
'-Wstrict-prototypes -std=c99 -Wextra -Wno-unused-parameter '
|
| 601 |
+
'-Wno-missing-field-initializers -I. -I./Include '
|
| 602 |
+
'-I/workspace/anaconda3/include '
|
| 603 |
+
'-fPIC -DPy_BUILD_CORE',
|
| 604 |
+
'PY_CPPFLAGS': '-I. -I./Include '
|
| 605 |
+
'-I/workspace/anaconda3/include',
|
| 606 |
+
'PY_FORMAT_SIZE_T': '"z"',
|
| 607 |
+
'PY_LDFLAGS': '-L/workspace/anaconda3/lib '
|
| 608 |
+
'-Wl,-rpath=/workspace/anaconda3/lib -Wl,--no-as-needed '
|
| 609 |
+
'-Wl,--sysroot=/',
|
| 610 |
+
'Py_DEBUG': 0,
|
| 611 |
+
'Py_ENABLE_SHARED': 0,
|
| 612 |
+
'Py_HASH_ALGORITHM': 0,
|
| 613 |
+
'QUICKTESTOPTS': '-x test_subprocess test_io test_lib2to3 \\',
|
| 614 |
+
'RANLIB': 'ranlib',
|
| 615 |
+
'READELF': 'readelf',
|
| 616 |
+
'RESSRCDIR': 'Mac/Resources/framework',
|
| 617 |
+
'RETSIGTYPE': 'void',
|
| 618 |
+
'RUNSHARED': 'LD_LIBRARY_PATH=/workspace/anaconda3/../work/Python-3.8.18',
|
| 619 |
+
'SCRIPTDIR': '/workspace/anaconda3/lib',
|
| 620 |
+
'SETPGRP_HAVE_ARG': 0,
|
| 621 |
+
'SGI_ABI': '',
|
| 622 |
+
'SHELL': '/bin/sh',
|
| 623 |
+
'SHLIBS': '-lpthread -ldl -lutil -lrt',
|
| 624 |
+
'SHLIB_SUFFIX': '.so',
|
| 625 |
+
'SIGNED_RIGHT_SHIFT_ZERO_FILLS': 0,
|
| 626 |
+
'SITEPATH': '',
|
| 627 |
+
'SIZEOF_DOUBLE': 8,
|
| 628 |
+
'SIZEOF_FLOAT': 4,
|
| 629 |
+
'SIZEOF_FPOS_T': 16,
|
| 630 |
+
'SIZEOF_INT': 4,
|
| 631 |
+
'SIZEOF_LONG': 8,
|
| 632 |
+
'SIZEOF_LONG_DOUBLE': 16,
|
| 633 |
+
'SIZEOF_LONG_LONG': 8,
|
| 634 |
+
'SIZEOF_OFF_T': 8,
|
| 635 |
+
'SIZEOF_PID_T': 4,
|
| 636 |
+
'SIZEOF_PTHREAD_T': 8,
|
| 637 |
+
'SIZEOF_SHORT': 2,
|
| 638 |
+
'SIZEOF_SIZE_T': 8,
|
| 639 |
+
'SIZEOF_TIME_T': 8,
|
| 640 |
+
'SIZEOF_UINTPTR_T': 8,
|
| 641 |
+
'SIZEOF_VOID_P': 8,
|
| 642 |
+
'SIZEOF_WCHAR_T': 4,
|
| 643 |
+
'SIZEOF__BOOL': 1,
|
| 644 |
+
'SOABI': 'cpython-38-x86_64-linux-gnu',
|
| 645 |
+
'SRCDIRS': 'Parser Grammar Objects Python Modules Mac Programs',
|
| 646 |
+
'SRC_GDB_HOOKS': './Tools/gdb/libpython.py',
|
| 647 |
+
'STDC_HEADERS': 1,
|
| 648 |
+
'STRICT_SYSV_CURSES': "/* Don't use ncurses extensions */",
|
| 649 |
+
'STRIPFLAG': '-s',
|
| 650 |
+
'SUBDIRS': '',
|
| 651 |
+
'SUBDIRSTOO': 'Include Lib Misc',
|
| 652 |
+
'SYSLIBS': '-lm',
|
| 653 |
+
'SYS_SELECT_WITH_SYS_TIME': 1,
|
| 654 |
+
'TANH_PRESERVES_ZERO_SIGN': 1,
|
| 655 |
+
'TCLTK_INCLUDES': '-I/workspace/anaconda3/include',
|
| 656 |
+
'TCLTK_LIBS': '-L/workspace/anaconda3/lib '
|
| 657 |
+
'-ltcl8.6 -ltk8.6',
|
| 658 |
+
'TESTOPTS': '',
|
| 659 |
+
'TESTPATH': '',
|
| 660 |
+
'TESTPYTHON': 'LD_LIBRARY_PATH=/workspace/anaconda3/../work/Python-3.8.18 '
|
| 661 |
+
'./python',
|
| 662 |
+
'TESTPYTHONOPTS': '',
|
| 663 |
+
'TESTRUNNER': 'LD_LIBRARY_PATH=/workspace/anaconda3/../work/Python-3.8.18 '
|
| 664 |
+
'./python ./Tools/scripts/run_tests.py',
|
| 665 |
+
'TESTTIMEOUT': 1200,
|
| 666 |
+
'THREADOBJ': 'Python/thread.o',
|
| 667 |
+
'TIMEMODULE_LIB': 'rt',
|
| 668 |
+
'TIME_WITH_SYS_TIME': 1,
|
| 669 |
+
'TM_IN_SYS_TIME': 0,
|
| 670 |
+
'UNICODE_DEPS': '\\',
|
| 671 |
+
'UNIVERSALSDK': '',
|
| 672 |
+
'USE_COMPUTED_GOTOS': 0,
|
| 673 |
+
'USE_INLINE': 1,
|
| 674 |
+
'VERSION': '3.8',
|
| 675 |
+
'WANT_SIGFPE_HANDLER': 0,
|
| 676 |
+
'WINDOW_HAS_FLAGS': 1,
|
| 677 |
+
'WITH_DOC_STRINGS': 1,
|
| 678 |
+
'WITH_DTRACE': 0,
|
| 679 |
+
'WITH_DYLD': 0,
|
| 680 |
+
'WITH_LIBINTL': 0,
|
| 681 |
+
'WITH_NEXT_FRAMEWORK': 0,
|
| 682 |
+
'WITH_PYMALLOC': 1,
|
| 683 |
+
'WITH_THREAD': 1,
|
| 684 |
+
'WITH_VALGRIND': 0,
|
| 685 |
+
'X87_DOUBLE_ROUNDING': 0,
|
| 686 |
+
'XMLLIBSUBDIRS': 'xml xml/dom xml/etree xml/parsers xml/sax',
|
| 687 |
+
'abs_builddir': '/workspace/anaconda3/../work/Python-3.8.18',
|
| 688 |
+
'abs_srcdir': '/workspace/anaconda3/../work/Python-3.8.18',
|
| 689 |
+
'datarootdir': '/workspace/anaconda3/share',
|
| 690 |
+
'exec_prefix': '/workspace/anaconda3',
|
| 691 |
+
'prefix': '/workspace/anaconda3',
|
| 692 |
+
'srcdir': '.'}
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata__linux_x86_64-linux-gnu.py.orig
ADDED
|
@@ -0,0 +1,952 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# system configuration generated and used by the sysconfig module
|
| 2 |
+
build_time_vars = {'ABIFLAGS': '',
|
| 3 |
+
'AC_APPLE_UNIVERSAL_BUILD': 0,
|
| 4 |
+
'AIX_GENUINE_CPLUSPLUS': 0,
|
| 5 |
+
'ALT_SOABI': 0,
|
| 6 |
+
'ANDROID_API_LEVEL': 0,
|
| 7 |
+
'AR': 'x86_64-conda-linux-gnu-ar',
|
| 8 |
+
'ARFLAGS': 'rcs',
|
| 9 |
+
'BASECFLAGS': '-Wno-unused-result -Wsign-compare',
|
| 10 |
+
'BASECPPFLAGS': '-IObjects -IInclude -IPython',
|
| 11 |
+
'BASEMODLIBS': '',
|
| 12 |
+
'BINDIR': '/workspace/anaconda3/bin',
|
| 13 |
+
'BINLIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 14 |
+
'BLDLIBRARY': 'libpython3.8.a',
|
| 15 |
+
'BLDSHARED': 'x86_64-conda-linux-gnu-gcc -pthread -shared -Wl,-O2 '
|
| 16 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 17 |
+
'-Wl,--disable-new-dtags -Wl,--gc-sections '
|
| 18 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 19 |
+
'-Wl,-rpath-link,/workspace/anaconda3/lib '
|
| 20 |
+
'-L/workspace/anaconda3/lib '
|
| 21 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 22 |
+
'-Wl,-z,now -Wl,--disable-new-dtags -Wl,--gc-sections '
|
| 23 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 24 |
+
'-Wl,-rpath-link,/workspace/anaconda3/lib '
|
| 25 |
+
'-L/workspace/anaconda3/lib',
|
| 26 |
+
'BUILDEXE': '',
|
| 27 |
+
'BUILDPYTHON': 'python',
|
| 28 |
+
'BUILD_GNU_TYPE': 'x86_64-conda-linux-gnu',
|
| 29 |
+
'BYTESTR_DEPS': '\\',
|
| 30 |
+
'CC': 'x86_64-conda-linux-gnu-gcc -pthread',
|
| 31 |
+
'CCSHARED': '-fPIC',
|
| 32 |
+
'CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall '
|
| 33 |
+
'-march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 34 |
+
'-fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe '
|
| 35 |
+
'-isystem '
|
| 36 |
+
'/workspace/anaconda3/include '
|
| 37 |
+
'-fdebug-prefix-map=/croot/python-split_1694437953337/work=/usr/local/src/conda/python-3.8.18 '
|
| 38 |
+
'-fdebug-prefix-map=/workspace/anaconda3=/usr/local/src/conda-prefix '
|
| 39 |
+
' '
|
| 40 |
+
'-march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 41 |
+
'-fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe '
|
| 42 |
+
'-isystem '
|
| 43 |
+
'/workspace/anaconda3/include '
|
| 44 |
+
'-fdebug-prefix-map=/croot/python-split_1694437953337/work=/usr/local/src/conda/python-3.8.18 '
|
| 45 |
+
'-fdebug-prefix-map=/workspace/anaconda3=/usr/local/src/conda-prefix '
|
| 46 |
+
' ',
|
| 47 |
+
'CFLAGSFORSHARED': '',
|
| 48 |
+
'CFLAGS_ALIASING': '',
|
| 49 |
+
'CONFIGFILES': 'configure configure.ac acconfig.h pyconfig.h.in '
|
| 50 |
+
'Makefile.pre.in',
|
| 51 |
+
'CONFIGURE_CFLAGS': '-march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 52 |
+
'-fstack-protector-strong -fno-plt -O2 '
|
| 53 |
+
'-ffunction-sections -pipe -isystem '
|
| 54 |
+
'/workspace/anaconda3/include '
|
| 55 |
+
'-fdebug-prefix-map=/croot/python-split_1694437953337/work=/usr/local/src/conda/python-3.8.18 '
|
| 56 |
+
'-fdebug-prefix-map=/workspace/anaconda3=/usr/local/src/conda-prefix '
|
| 57 |
+
' '
|
| 58 |
+
' ',
|
| 59 |
+
'CONFIGURE_CFLAGS_NODIST': ' '
|
| 60 |
+
' -g -std=c99 -Wextra '
|
| 61 |
+
'-Wno-unused-result -Wno-unused-parameter '
|
| 62 |
+
'-Wno-missing-field-initializers '
|
| 63 |
+
'-Werror=implicit-function-declaration',
|
| 64 |
+
'CONFIGURE_CPPFLAGS': '-DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem '
|
| 65 |
+
'/workspace/anaconda3/include '
|
| 66 |
+
'-I/workspace/anaconda3/include',
|
| 67 |
+
'CONFIGURE_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 68 |
+
'-Wl,-z,now -Wl,--disable-new-dtags -Wl,--gc-sections '
|
| 69 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 70 |
+
'-Wl,-rpath-link,/workspace/anaconda3/lib '
|
| 71 |
+
'-L/workspace/anaconda3/lib',
|
| 72 |
+
'CONFIGURE_LDFLAGS_NODIST': ' '
|
| 73 |
+
' -g',
|
| 74 |
+
'CONFIG_ARGS': "'--prefix=/workspace/anaconda3' "
|
| 75 |
+
"'--build=x86_64-conda-linux-gnu' "
|
| 76 |
+
"'--host=x86_64-conda-linux-gnu' '--enable-ipv6' "
|
| 77 |
+
"'--with-ensurepip=no' '--with-computed-gotos' "
|
| 78 |
+
"'--with-system-ffi' '--enable-loadable-sqlite-extensions' "
|
| 79 |
+
"'--with-openssl=/workspace/anaconda3' "
|
| 80 |
+
"'--with-tcltk-includes=-I/workspace/anaconda3/include' "
|
| 81 |
+
"'--with-tcltk-libs=-L/workspace/anaconda3/lib "
|
| 82 |
+
"-ltcl8.6 -ltk8.6' '--with-lto' '--enable-optimizations' "
|
| 83 |
+
"'-oldincludedir=/croot/python-split_1694437953337/_build_env/x86_64-conda-linux-gnu/sysroot/usr/include' "
|
| 84 |
+
"'--disable-shared' 'PROFILE_TASK=-m test --pgo' "
|
| 85 |
+
"'build_alias=x86_64-conda-linux-gnu' "
|
| 86 |
+
"'host_alias=x86_64-conda-linux-gnu' 'MACHDEP=linux' "
|
| 87 |
+
"'CC=x86_64-conda-linux-gnu-gcc' 'CFLAGS=-march=nocona "
|
| 88 |
+
'-mtune=haswell -ftree-vectorize -fPIC '
|
| 89 |
+
'-fstack-protector-strong -fno-plt -O2 -ffunction-sections '
|
| 90 |
+
'-pipe -isystem '
|
| 91 |
+
'/workspace/anaconda3/include '
|
| 92 |
+
'-fdebug-prefix-map=/croot/python-split_1694437953337/work=/usr/local/src/conda/python-3.8.18 '
|
| 93 |
+
'-fdebug-prefix-map=/workspace/anaconda3=/usr/local/src/conda-prefix '
|
| 94 |
+
' '
|
| 95 |
+
"' 'LDFLAGS=-Wl,-O2 -Wl,--sort-common -Wl,--as-needed "
|
| 96 |
+
'-Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags '
|
| 97 |
+
'-Wl,--gc-sections '
|
| 98 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 99 |
+
'-Wl,-rpath-link,/workspace/anaconda3/lib '
|
| 100 |
+
"-L/workspace/anaconda3/lib' "
|
| 101 |
+
"'CPPFLAGS=-DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem "
|
| 102 |
+
'/workspace/anaconda3/include '
|
| 103 |
+
"-I/workspace/anaconda3/include' "
|
| 104 |
+
"'CPP=/croot/python-split_1694437953337/_build_env/bin/x86_64-conda-linux-gnu-cpp' "
|
| 105 |
+
"'PKG_CONFIG_PATH=/workspace/anaconda3/lib/pkgconfig'",
|
| 106 |
+
'CONFINCLUDEDIR': '/workspace/anaconda3/include',
|
| 107 |
+
'CONFINCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 108 |
+
'COREPYTHONPATH': '',
|
| 109 |
+
'COVERAGE_INFO': '/croot/python-split_1694437953337/work/build-static/coverage.info',
|
| 110 |
+
'COVERAGE_REPORT': '/croot/python-split_1694437953337/work/build-static/lcov-report',
|
| 111 |
+
'COVERAGE_REPORT_OPTIONS': '--no-branch-coverage --title "CPython lcov '
|
| 112 |
+
'report"',
|
| 113 |
+
'CPPFLAGS': '-IObjects -IInclude -IPython -I. '
|
| 114 |
+
'-I/croot/python-split_1694437953337/work/Include -DNDEBUG '
|
| 115 |
+
'-D_FORTIFY_SOURCE=2 -O2 -isystem '
|
| 116 |
+
'/workspace/anaconda3/include '
|
| 117 |
+
'-I/workspace/anaconda3/include '
|
| 118 |
+
'-DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem '
|
| 119 |
+
'/workspace/anaconda3/include '
|
| 120 |
+
'-I/workspace/anaconda3/include',
|
| 121 |
+
'CXX': 'x86_64-conda-linux-gnu-c++ -pthread',
|
| 122 |
+
'DESTDIRS': '/workspace/anaconda3 '
|
| 123 |
+
'/workspace/anaconda3/lib '
|
| 124 |
+
'/workspace/anaconda3/lib/python3.8 '
|
| 125 |
+
'/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 126 |
+
'DESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 127 |
+
'DESTPATH': '',
|
| 128 |
+
'DESTSHARED': '/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 129 |
+
'DFLAGS': '',
|
| 130 |
+
'DIRMODE': 755,
|
| 131 |
+
'DIST': 'README.rst ChangeLog configure configure.ac acconfig.h pyconfig.h.in '
|
| 132 |
+
'Makefile.pre.in Include Lib Misc Ext-dummy',
|
| 133 |
+
'DISTDIRS': 'Include Lib Misc Ext-dummy',
|
| 134 |
+
'DISTFILES': 'README.rst ChangeLog configure configure.ac acconfig.h '
|
| 135 |
+
'pyconfig.h.in Makefile.pre.in',
|
| 136 |
+
'DLINCLDIR': '.',
|
| 137 |
+
'DLLLIBRARY': '',
|
| 138 |
+
'DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754': 0,
|
| 139 |
+
'DOUBLE_IS_BIG_ENDIAN_IEEE754': 0,
|
| 140 |
+
'DOUBLE_IS_LITTLE_ENDIAN_IEEE754': 1,
|
| 141 |
+
'DTRACE': '',
|
| 142 |
+
'DTRACE_DEPS': '\\',
|
| 143 |
+
'DTRACE_HEADERS': '',
|
| 144 |
+
'DTRACE_OBJS': '',
|
| 145 |
+
'DYNLOADFILE': 'dynload_shlib.o',
|
| 146 |
+
'ENABLE_IPV6': 1,
|
| 147 |
+
'ENSUREPIP': 'no',
|
| 148 |
+
'EXE': '',
|
| 149 |
+
'EXEMODE': 755,
|
| 150 |
+
'EXTRATESTOPTS': '',
|
| 151 |
+
'EXT_SUFFIX': '.cpython-38-x86_64-linux-gnu.so',
|
| 152 |
+
'FILEMODE': 644,
|
| 153 |
+
'FLOAT_WORDS_BIGENDIAN': 0,
|
| 154 |
+
'FLOCK_NEEDS_LIBBSD': 0,
|
| 155 |
+
'GETPGRP_HAVE_ARG': 0,
|
| 156 |
+
'GETTIMEOFDAY_NO_TZ': 0,
|
| 157 |
+
'GITBRANCH': '',
|
| 158 |
+
'GITTAG': '',
|
| 159 |
+
'GITVERSION': '',
|
| 160 |
+
'GNULD': 'yes',
|
| 161 |
+
'HAVE_ACCEPT4': 1,
|
| 162 |
+
'HAVE_ACOSH': 1,
|
| 163 |
+
'HAVE_ADDRINFO': 1,
|
| 164 |
+
'HAVE_ALARM': 1,
|
| 165 |
+
'HAVE_ALIGNED_REQUIRED': 0,
|
| 166 |
+
'HAVE_ALLOCA_H': 1,
|
| 167 |
+
'HAVE_ALTZONE': 0,
|
| 168 |
+
'HAVE_ASINH': 1,
|
| 169 |
+
'HAVE_ASM_TYPES_H': 1,
|
| 170 |
+
'HAVE_ATANH': 1,
|
| 171 |
+
'HAVE_BIND_TEXTDOMAIN_CODESET': 1,
|
| 172 |
+
'HAVE_BLUETOOTH_BLUETOOTH_H': 0,
|
| 173 |
+
'HAVE_BLUETOOTH_H': 0,
|
| 174 |
+
'HAVE_BROKEN_MBSTOWCS': 0,
|
| 175 |
+
'HAVE_BROKEN_NICE': 0,
|
| 176 |
+
'HAVE_BROKEN_PIPE_BUF': 0,
|
| 177 |
+
'HAVE_BROKEN_POLL': 0,
|
| 178 |
+
'HAVE_BROKEN_POSIX_SEMAPHORES': 0,
|
| 179 |
+
'HAVE_BROKEN_PTHREAD_SIGMASK': 0,
|
| 180 |
+
'HAVE_BROKEN_SEM_GETVALUE': 0,
|
| 181 |
+
'HAVE_BROKEN_UNSETENV': 0,
|
| 182 |
+
'HAVE_BUILTIN_ATOMIC': 1,
|
| 183 |
+
'HAVE_CHFLAGS': 0,
|
| 184 |
+
'HAVE_CHOWN': 1,
|
| 185 |
+
'HAVE_CHROOT': 1,
|
| 186 |
+
'HAVE_CLOCK': 1,
|
| 187 |
+
'HAVE_CLOCK_GETRES': 1,
|
| 188 |
+
'HAVE_CLOCK_GETTIME': 1,
|
| 189 |
+
'HAVE_CLOCK_SETTIME': 1,
|
| 190 |
+
'HAVE_COMPUTED_GOTOS': 1,
|
| 191 |
+
'HAVE_CONFSTR': 1,
|
| 192 |
+
'HAVE_CONIO_H': 0,
|
| 193 |
+
'HAVE_COPYSIGN': 1,
|
| 194 |
+
'HAVE_COPY_FILE_RANGE': 0,
|
| 195 |
+
'HAVE_CRYPT_H': 1,
|
| 196 |
+
'HAVE_CRYPT_R': 1,
|
| 197 |
+
'HAVE_CTERMID': 1,
|
| 198 |
+
'HAVE_CTERMID_R': 0,
|
| 199 |
+
'HAVE_CURSES_FILTER': 1,
|
| 200 |
+
'HAVE_CURSES_H': 1,
|
| 201 |
+
'HAVE_CURSES_HAS_KEY': 1,
|
| 202 |
+
'HAVE_CURSES_IMMEDOK': 1,
|
| 203 |
+
'HAVE_CURSES_IS_PAD': 1,
|
| 204 |
+
'HAVE_CURSES_IS_TERM_RESIZED': 1,
|
| 205 |
+
'HAVE_CURSES_RESIZETERM': 1,
|
| 206 |
+
'HAVE_CURSES_RESIZE_TERM': 1,
|
| 207 |
+
'HAVE_CURSES_SYNCOK': 1,
|
| 208 |
+
'HAVE_CURSES_TYPEAHEAD': 1,
|
| 209 |
+
'HAVE_CURSES_USE_ENV': 1,
|
| 210 |
+
'HAVE_CURSES_WCHGAT': 1,
|
| 211 |
+
'HAVE_DECL_ISFINITE': 1,
|
| 212 |
+
'HAVE_DECL_ISINF': 1,
|
| 213 |
+
'HAVE_DECL_ISNAN': 1,
|
| 214 |
+
'HAVE_DECL_RTLD_DEEPBIND': 1,
|
| 215 |
+
'HAVE_DECL_RTLD_GLOBAL': 1,
|
| 216 |
+
'HAVE_DECL_RTLD_LAZY': 1,
|
| 217 |
+
'HAVE_DECL_RTLD_LOCAL': 1,
|
| 218 |
+
'HAVE_DECL_RTLD_MEMBER': 0,
|
| 219 |
+
'HAVE_DECL_RTLD_NODELETE': 1,
|
| 220 |
+
'HAVE_DECL_RTLD_NOLOAD': 1,
|
| 221 |
+
'HAVE_DECL_RTLD_NOW': 1,
|
| 222 |
+
'HAVE_DECL_TZNAME': 0,
|
| 223 |
+
'HAVE_DEVICE_MACROS': 1,
|
| 224 |
+
'HAVE_DEV_PTC': 0,
|
| 225 |
+
'HAVE_DEV_PTMX': 1,
|
| 226 |
+
'HAVE_DIRECT_H': 0,
|
| 227 |
+
'HAVE_DIRENT_D_TYPE': 1,
|
| 228 |
+
'HAVE_DIRENT_H': 1,
|
| 229 |
+
'HAVE_DIRFD': 1,
|
| 230 |
+
'HAVE_DLFCN_H': 1,
|
| 231 |
+
'HAVE_DLOPEN': 1,
|
| 232 |
+
'HAVE_DUP2': 1,
|
| 233 |
+
'HAVE_DUP3': 1,
|
| 234 |
+
'HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH': 0,
|
| 235 |
+
'HAVE_DYNAMIC_LOADING': 1,
|
| 236 |
+
'HAVE_ENDIAN_H': 1,
|
| 237 |
+
'HAVE_EPOLL': 1,
|
| 238 |
+
'HAVE_EPOLL_CREATE1': 1,
|
| 239 |
+
'HAVE_ERF': 1,
|
| 240 |
+
'HAVE_ERFC': 1,
|
| 241 |
+
'HAVE_ERRNO_H': 1,
|
| 242 |
+
'HAVE_EXECV': 1,
|
| 243 |
+
'HAVE_EXPLICIT_BZERO': 0,
|
| 244 |
+
'HAVE_EXPLICIT_MEMSET': 0,
|
| 245 |
+
'HAVE_EXPM1': 1,
|
| 246 |
+
'HAVE_FACCESSAT': 1,
|
| 247 |
+
'HAVE_FCHDIR': 1,
|
| 248 |
+
'HAVE_FCHMOD': 1,
|
| 249 |
+
'HAVE_FCHMODAT': 1,
|
| 250 |
+
'HAVE_FCHOWN': 1,
|
| 251 |
+
'HAVE_FCHOWNAT': 1,
|
| 252 |
+
'HAVE_FCNTL_H': 1,
|
| 253 |
+
'HAVE_FDATASYNC': 1,
|
| 254 |
+
'HAVE_FDOPENDIR': 1,
|
| 255 |
+
'HAVE_FDWALK': 0,
|
| 256 |
+
'HAVE_FEXECVE': 1,
|
| 257 |
+
'HAVE_FINITE': 1,
|
| 258 |
+
'HAVE_FLOCK': 1,
|
| 259 |
+
'HAVE_FORK': 1,
|
| 260 |
+
'HAVE_FORKPTY': 1,
|
| 261 |
+
'HAVE_FPATHCONF': 1,
|
| 262 |
+
'HAVE_FSEEK64': 0,
|
| 263 |
+
'HAVE_FSEEKO': 1,
|
| 264 |
+
'HAVE_FSTATAT': 1,
|
| 265 |
+
'HAVE_FSTATVFS': 1,
|
| 266 |
+
'HAVE_FSYNC': 1,
|
| 267 |
+
'HAVE_FTELL64': 0,
|
| 268 |
+
'HAVE_FTELLO': 1,
|
| 269 |
+
'HAVE_FTIME': 1,
|
| 270 |
+
'HAVE_FTRUNCATE': 1,
|
| 271 |
+
'HAVE_FUTIMENS': 1,
|
| 272 |
+
'HAVE_FUTIMES': 1,
|
| 273 |
+
'HAVE_FUTIMESAT': 1,
|
| 274 |
+
'HAVE_GAI_STRERROR': 1,
|
| 275 |
+
'HAVE_GAMMA': 1,
|
| 276 |
+
'HAVE_GCC_ASM_FOR_MC68881': 0,
|
| 277 |
+
'HAVE_GCC_ASM_FOR_X64': 1,
|
| 278 |
+
'HAVE_GCC_ASM_FOR_X87': 1,
|
| 279 |
+
'HAVE_GCC_UINT128_T': 1,
|
| 280 |
+
'HAVE_GETADDRINFO': 1,
|
| 281 |
+
'HAVE_GETC_UNLOCKED': 1,
|
| 282 |
+
'HAVE_GETENTROPY': 0,
|
| 283 |
+
'HAVE_GETGRGID_R': 1,
|
| 284 |
+
'HAVE_GETGRNAM_R': 1,
|
| 285 |
+
'HAVE_GETGROUPLIST': 1,
|
| 286 |
+
'HAVE_GETGROUPS': 1,
|
| 287 |
+
'HAVE_GETHOSTBYNAME': 0,
|
| 288 |
+
'HAVE_GETHOSTBYNAME_R': 1,
|
| 289 |
+
'HAVE_GETHOSTBYNAME_R_3_ARG': 0,
|
| 290 |
+
'HAVE_GETHOSTBYNAME_R_5_ARG': 0,
|
| 291 |
+
'HAVE_GETHOSTBYNAME_R_6_ARG': 1,
|
| 292 |
+
'HAVE_GETITIMER': 1,
|
| 293 |
+
'HAVE_GETLOADAVG': 1,
|
| 294 |
+
'HAVE_GETLOGIN': 1,
|
| 295 |
+
'HAVE_GETNAMEINFO': 1,
|
| 296 |
+
'HAVE_GETPAGESIZE': 1,
|
| 297 |
+
'HAVE_GETPEERNAME': 1,
|
| 298 |
+
'HAVE_GETPGID': 1,
|
| 299 |
+
'HAVE_GETPGRP': 1,
|
| 300 |
+
'HAVE_GETPID': 1,
|
| 301 |
+
'HAVE_GETPRIORITY': 1,
|
| 302 |
+
'HAVE_GETPWENT': 1,
|
| 303 |
+
'HAVE_GETPWNAM_R': 1,
|
| 304 |
+
'HAVE_GETPWUID_R': 1,
|
| 305 |
+
'HAVE_GETRANDOM': 0,
|
| 306 |
+
'HAVE_GETRANDOM_SYSCALL': 1,
|
| 307 |
+
'HAVE_GETRESGID': 1,
|
| 308 |
+
'HAVE_GETRESUID': 1,
|
| 309 |
+
'HAVE_GETSID': 1,
|
| 310 |
+
'HAVE_GETSPENT': 1,
|
| 311 |
+
'HAVE_GETSPNAM': 1,
|
| 312 |
+
'HAVE_GETTIMEOFDAY': 1,
|
| 313 |
+
'HAVE_GETWD': 1,
|
| 314 |
+
'HAVE_GLIBC_MEMMOVE_BUG': 0,
|
| 315 |
+
'HAVE_GRP_H': 1,
|
| 316 |
+
'HAVE_HSTRERROR': 1,
|
| 317 |
+
'HAVE_HTOLE64': 1,
|
| 318 |
+
'HAVE_HYPOT': 1,
|
| 319 |
+
'HAVE_IEEEFP_H': 0,
|
| 320 |
+
'HAVE_IF_NAMEINDEX': 1,
|
| 321 |
+
'HAVE_INET_ATON': 1,
|
| 322 |
+
'HAVE_INET_PTON': 1,
|
| 323 |
+
'HAVE_INITGROUPS': 1,
|
| 324 |
+
'HAVE_INTTYPES_H': 1,
|
| 325 |
+
'HAVE_IO_H': 0,
|
| 326 |
+
'HAVE_IPA_PURE_CONST_BUG': 0,
|
| 327 |
+
'HAVE_KILL': 1,
|
| 328 |
+
'HAVE_KILLPG': 1,
|
| 329 |
+
'HAVE_KQUEUE': 0,
|
| 330 |
+
'HAVE_LANGINFO_H': 1,
|
| 331 |
+
'HAVE_LARGEFILE_SUPPORT': 0,
|
| 332 |
+
'HAVE_LCHFLAGS': 0,
|
| 333 |
+
'HAVE_LCHMOD': 0,
|
| 334 |
+
'HAVE_LCHOWN': 1,
|
| 335 |
+
'HAVE_LGAMMA': 1,
|
| 336 |
+
'HAVE_LIBDL': 1,
|
| 337 |
+
'HAVE_LIBDLD': 0,
|
| 338 |
+
'HAVE_LIBIEEE': 0,
|
| 339 |
+
'HAVE_LIBINTL_H': 1,
|
| 340 |
+
'HAVE_LIBREADLINE': 1,
|
| 341 |
+
'HAVE_LIBRESOLV': 0,
|
| 342 |
+
'HAVE_LIBSENDFILE': 0,
|
| 343 |
+
'HAVE_LIBUTIL_H': 0,
|
| 344 |
+
'HAVE_LINK': 1,
|
| 345 |
+
'HAVE_LINKAT': 1,
|
| 346 |
+
'HAVE_LINUX_CAN_BCM_H': 1,
|
| 347 |
+
'HAVE_LINUX_CAN_H': 1,
|
| 348 |
+
'HAVE_LINUX_CAN_RAW_FD_FRAMES': 1,
|
| 349 |
+
'HAVE_LINUX_CAN_RAW_H': 1,
|
| 350 |
+
'HAVE_LINUX_MEMFD_H': 1,
|
| 351 |
+
'HAVE_LINUX_NETLINK_H': 1,
|
| 352 |
+
'HAVE_LINUX_QRTR_H': 0,
|
| 353 |
+
'HAVE_LINUX_RANDOM_H': 1,
|
| 354 |
+
'HAVE_LINUX_TIPC_H': 1,
|
| 355 |
+
'HAVE_LINUX_VM_SOCKETS_H': 1,
|
| 356 |
+
'HAVE_LOCKF': 1,
|
| 357 |
+
'HAVE_LOG1P': 1,
|
| 358 |
+
'HAVE_LOG2': 1,
|
| 359 |
+
'HAVE_LONG_DOUBLE': 1,
|
| 360 |
+
'HAVE_LSTAT': 1,
|
| 361 |
+
'HAVE_LUTIMES': 1,
|
| 362 |
+
'HAVE_MADVISE': 1,
|
| 363 |
+
'HAVE_MAKEDEV': 1,
|
| 364 |
+
'HAVE_MBRTOWC': 1,
|
| 365 |
+
'HAVE_MEMFD_CREATE': 0,
|
| 366 |
+
'HAVE_MEMORY_H': 1,
|
| 367 |
+
'HAVE_MEMRCHR': 1,
|
| 368 |
+
'HAVE_MKDIRAT': 1,
|
| 369 |
+
'HAVE_MKFIFO': 1,
|
| 370 |
+
'HAVE_MKFIFOAT': 1,
|
| 371 |
+
'HAVE_MKNOD': 1,
|
| 372 |
+
'HAVE_MKNODAT': 1,
|
| 373 |
+
'HAVE_MKTIME': 1,
|
| 374 |
+
'HAVE_MMAP': 1,
|
| 375 |
+
'HAVE_MREMAP': 1,
|
| 376 |
+
'HAVE_NCURSES_H': 1,
|
| 377 |
+
'HAVE_NDIR_H': 0,
|
| 378 |
+
'HAVE_NETPACKET_PACKET_H': 1,
|
| 379 |
+
'HAVE_NET_IF_H': 1,
|
| 380 |
+
'HAVE_NICE': 1,
|
| 381 |
+
'HAVE_OPENAT': 1,
|
| 382 |
+
'HAVE_OPENPTY': 1,
|
| 383 |
+
'HAVE_PATHCONF': 1,
|
| 384 |
+
'HAVE_PAUSE': 1,
|
| 385 |
+
'HAVE_PIPE2': 1,
|
| 386 |
+
'HAVE_PLOCK': 0,
|
| 387 |
+
'HAVE_POLL': 1,
|
| 388 |
+
'HAVE_POLL_H': 1,
|
| 389 |
+
'HAVE_POSIX_FADVISE': 1,
|
| 390 |
+
'HAVE_POSIX_FALLOCATE': 1,
|
| 391 |
+
'HAVE_POSIX_SPAWN': 1,
|
| 392 |
+
'HAVE_POSIX_SPAWNP': 1,
|
| 393 |
+
'HAVE_PREAD': 1,
|
| 394 |
+
'HAVE_PREADV': 1,
|
| 395 |
+
'HAVE_PREADV2': 0,
|
| 396 |
+
'HAVE_PRLIMIT': 1,
|
| 397 |
+
'HAVE_PROCESS_H': 0,
|
| 398 |
+
'HAVE_PROTOTYPES': 1,
|
| 399 |
+
'HAVE_PTHREAD_CONDATTR_SETCLOCK': 1,
|
| 400 |
+
'HAVE_PTHREAD_DESTRUCTOR': 0,
|
| 401 |
+
'HAVE_PTHREAD_GETCPUCLOCKID': 1,
|
| 402 |
+
'HAVE_PTHREAD_H': 1,
|
| 403 |
+
'HAVE_PTHREAD_INIT': 0,
|
| 404 |
+
'HAVE_PTHREAD_KILL': 1,
|
| 405 |
+
'HAVE_PTHREAD_SIGMASK': 1,
|
| 406 |
+
'HAVE_PTY_H': 1,
|
| 407 |
+
'HAVE_PUTENV': 1,
|
| 408 |
+
'HAVE_PWRITE': 1,
|
| 409 |
+
'HAVE_PWRITEV': 1,
|
| 410 |
+
'HAVE_PWRITEV2': 0,
|
| 411 |
+
'HAVE_READLINK': 1,
|
| 412 |
+
'HAVE_READLINKAT': 1,
|
| 413 |
+
'HAVE_READV': 1,
|
| 414 |
+
'HAVE_REALPATH': 1,
|
| 415 |
+
'HAVE_RENAMEAT': 1,
|
| 416 |
+
'HAVE_RL_APPEND_HISTORY': 1,
|
| 417 |
+
'HAVE_RL_CATCH_SIGNAL': 1,
|
| 418 |
+
'HAVE_RL_COMPLETION_APPEND_CHARACTER': 1,
|
| 419 |
+
'HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK': 1,
|
| 420 |
+
'HAVE_RL_COMPLETION_MATCHES': 1,
|
| 421 |
+
'HAVE_RL_COMPLETION_SUPPRESS_APPEND': 1,
|
| 422 |
+
'HAVE_RL_PRE_INPUT_HOOK': 1,
|
| 423 |
+
'HAVE_RL_RESIZE_TERMINAL': 1,
|
| 424 |
+
'HAVE_ROUND': 1,
|
| 425 |
+
'HAVE_RTPSPAWN': 0,
|
| 426 |
+
'HAVE_SCHED_GET_PRIORITY_MAX': 1,
|
| 427 |
+
'HAVE_SCHED_H': 1,
|
| 428 |
+
'HAVE_SCHED_RR_GET_INTERVAL': 1,
|
| 429 |
+
'HAVE_SCHED_SETAFFINITY': 1,
|
| 430 |
+
'HAVE_SCHED_SETPARAM': 1,
|
| 431 |
+
'HAVE_SCHED_SETSCHEDULER': 1,
|
| 432 |
+
'HAVE_SEM_GETVALUE': 1,
|
| 433 |
+
'HAVE_SEM_OPEN': 1,
|
| 434 |
+
'HAVE_SEM_TIMEDWAIT': 1,
|
| 435 |
+
'HAVE_SEM_UNLINK': 1,
|
| 436 |
+
'HAVE_SENDFILE': 1,
|
| 437 |
+
'HAVE_SETEGID': 1,
|
| 438 |
+
'HAVE_SETEUID': 1,
|
| 439 |
+
'HAVE_SETGID': 1,
|
| 440 |
+
'HAVE_SETGROUPS': 1,
|
| 441 |
+
'HAVE_SETHOSTNAME': 1,
|
| 442 |
+
'HAVE_SETITIMER': 1,
|
| 443 |
+
'HAVE_SETLOCALE': 1,
|
| 444 |
+
'HAVE_SETPGID': 1,
|
| 445 |
+
'HAVE_SETPGRP': 1,
|
| 446 |
+
'HAVE_SETPRIORITY': 1,
|
| 447 |
+
'HAVE_SETREGID': 1,
|
| 448 |
+
'HAVE_SETRESGID': 1,
|
| 449 |
+
'HAVE_SETRESUID': 1,
|
| 450 |
+
'HAVE_SETREUID': 1,
|
| 451 |
+
'HAVE_SETSID': 1,
|
| 452 |
+
'HAVE_SETUID': 1,
|
| 453 |
+
'HAVE_SETVBUF': 1,
|
| 454 |
+
'HAVE_SHADOW_H': 1,
|
| 455 |
+
'HAVE_SHM_OPEN': 1,
|
| 456 |
+
'HAVE_SHM_UNLINK': 1,
|
| 457 |
+
'HAVE_SIGACTION': 1,
|
| 458 |
+
'HAVE_SIGALTSTACK': 1,
|
| 459 |
+
'HAVE_SIGFILLSET': 1,
|
| 460 |
+
'HAVE_SIGINFO_T_SI_BAND': 1,
|
| 461 |
+
'HAVE_SIGINTERRUPT': 1,
|
| 462 |
+
'HAVE_SIGNAL_H': 1,
|
| 463 |
+
'HAVE_SIGPENDING': 1,
|
| 464 |
+
'HAVE_SIGRELSE': 1,
|
| 465 |
+
'HAVE_SIGTIMEDWAIT': 1,
|
| 466 |
+
'HAVE_SIGWAIT': 1,
|
| 467 |
+
'HAVE_SIGWAITINFO': 1,
|
| 468 |
+
'HAVE_SNPRINTF': 1,
|
| 469 |
+
'HAVE_SOCKADDR_ALG': 1,
|
| 470 |
+
'HAVE_SOCKADDR_SA_LEN': 0,
|
| 471 |
+
'HAVE_SOCKADDR_STORAGE': 1,
|
| 472 |
+
'HAVE_SOCKETPAIR': 1,
|
| 473 |
+
'HAVE_SPAWN_H': 1,
|
| 474 |
+
'HAVE_SSIZE_T': 1,
|
| 475 |
+
'HAVE_STATVFS': 1,
|
| 476 |
+
'HAVE_STAT_TV_NSEC': 1,
|
| 477 |
+
'HAVE_STAT_TV_NSEC2': 0,
|
| 478 |
+
'HAVE_STDARG_PROTOTYPES': 1,
|
| 479 |
+
'HAVE_STDINT_H': 1,
|
| 480 |
+
'HAVE_STDLIB_H': 1,
|
| 481 |
+
'HAVE_STD_ATOMIC': 1,
|
| 482 |
+
'HAVE_STRDUP': 1,
|
| 483 |
+
'HAVE_STRFTIME': 1,
|
| 484 |
+
'HAVE_STRINGS_H': 1,
|
| 485 |
+
'HAVE_STRING_H': 1,
|
| 486 |
+
'HAVE_STRLCPY': 0,
|
| 487 |
+
'HAVE_STROPTS_H': 0,
|
| 488 |
+
'HAVE_STRSIGNAL': 1,
|
| 489 |
+
'HAVE_STRUCT_PASSWD_PW_GECOS': 1,
|
| 490 |
+
'HAVE_STRUCT_PASSWD_PW_PASSWD': 1,
|
| 491 |
+
'HAVE_STRUCT_STAT_ST_BIRTHTIME': 0,
|
| 492 |
+
'HAVE_STRUCT_STAT_ST_BLKSIZE': 1,
|
| 493 |
+
'HAVE_STRUCT_STAT_ST_BLOCKS': 1,
|
| 494 |
+
'HAVE_STRUCT_STAT_ST_FLAGS': 0,
|
| 495 |
+
'HAVE_STRUCT_STAT_ST_GEN': 0,
|
| 496 |
+
'HAVE_STRUCT_STAT_ST_RDEV': 1,
|
| 497 |
+
'HAVE_STRUCT_TM_TM_ZONE': 1,
|
| 498 |
+
'HAVE_SYMLINK': 1,
|
| 499 |
+
'HAVE_SYMLINKAT': 1,
|
| 500 |
+
'HAVE_SYNC': 1,
|
| 501 |
+
'HAVE_SYSCONF': 1,
|
| 502 |
+
'HAVE_SYSEXITS_H': 1,
|
| 503 |
+
'HAVE_SYS_AUDIOIO_H': 0,
|
| 504 |
+
'HAVE_SYS_BSDTTY_H': 0,
|
| 505 |
+
'HAVE_SYS_DEVPOLL_H': 0,
|
| 506 |
+
'HAVE_SYS_DIR_H': 0,
|
| 507 |
+
'HAVE_SYS_ENDIAN_H': 0,
|
| 508 |
+
'HAVE_SYS_EPOLL_H': 1,
|
| 509 |
+
'HAVE_SYS_EVENT_H': 0,
|
| 510 |
+
'HAVE_SYS_FILE_H': 1,
|
| 511 |
+
'HAVE_SYS_IOCTL_H': 1,
|
| 512 |
+
'HAVE_SYS_KERN_CONTROL_H': 0,
|
| 513 |
+
'HAVE_SYS_LOADAVG_H': 0,
|
| 514 |
+
'HAVE_SYS_LOCK_H': 0,
|
| 515 |
+
'HAVE_SYS_MEMFD_H': 0,
|
| 516 |
+
'HAVE_SYS_MKDEV_H': 0,
|
| 517 |
+
'HAVE_SYS_MMAN_H': 1,
|
| 518 |
+
'HAVE_SYS_MODEM_H': 0,
|
| 519 |
+
'HAVE_SYS_NDIR_H': 0,
|
| 520 |
+
'HAVE_SYS_PARAM_H': 1,
|
| 521 |
+
'HAVE_SYS_POLL_H': 1,
|
| 522 |
+
'HAVE_SYS_RANDOM_H': 0,
|
| 523 |
+
'HAVE_SYS_RESOURCE_H': 1,
|
| 524 |
+
'HAVE_SYS_SELECT_H': 1,
|
| 525 |
+
'HAVE_SYS_SENDFILE_H': 1,
|
| 526 |
+
'HAVE_SYS_SOCKET_H': 1,
|
| 527 |
+
'HAVE_SYS_STATVFS_H': 1,
|
| 528 |
+
'HAVE_SYS_STAT_H': 1,
|
| 529 |
+
'HAVE_SYS_SYSCALL_H': 1,
|
| 530 |
+
'HAVE_SYS_SYSMACROS_H': 1,
|
| 531 |
+
'HAVE_SYS_SYS_DOMAIN_H': 0,
|
| 532 |
+
'HAVE_SYS_TERMIO_H': 0,
|
| 533 |
+
'HAVE_SYS_TIMES_H': 1,
|
| 534 |
+
'HAVE_SYS_TIME_H': 1,
|
| 535 |
+
'HAVE_SYS_TYPES_H': 1,
|
| 536 |
+
'HAVE_SYS_UIO_H': 1,
|
| 537 |
+
'HAVE_SYS_UN_H': 1,
|
| 538 |
+
'HAVE_SYS_UTSNAME_H': 1,
|
| 539 |
+
'HAVE_SYS_WAIT_H': 1,
|
| 540 |
+
'HAVE_SYS_XATTR_H': 1,
|
| 541 |
+
'HAVE_TCGETPGRP': 1,
|
| 542 |
+
'HAVE_TCSETPGRP': 1,
|
| 543 |
+
'HAVE_TEMPNAM': 1,
|
| 544 |
+
'HAVE_TERMIOS_H': 1,
|
| 545 |
+
'HAVE_TERM_H': 1,
|
| 546 |
+
'HAVE_TGAMMA': 1,
|
| 547 |
+
'HAVE_TIMEGM': 1,
|
| 548 |
+
'HAVE_TIMES': 1,
|
| 549 |
+
'HAVE_TMPFILE': 1,
|
| 550 |
+
'HAVE_TMPNAM': 1,
|
| 551 |
+
'HAVE_TMPNAM_R': 1,
|
| 552 |
+
'HAVE_TM_ZONE': 1,
|
| 553 |
+
'HAVE_TRUNCATE': 1,
|
| 554 |
+
'HAVE_TZNAME': 0,
|
| 555 |
+
'HAVE_UCS4_TCL': 0,
|
| 556 |
+
'HAVE_UNAME': 1,
|
| 557 |
+
'HAVE_UNISTD_H': 1,
|
| 558 |
+
'HAVE_UNLINKAT': 1,
|
| 559 |
+
'HAVE_UNSETENV': 1,
|
| 560 |
+
'HAVE_USABLE_WCHAR_T': 0,
|
| 561 |
+
'HAVE_UTIL_H': 0,
|
| 562 |
+
'HAVE_UTIMENSAT': 1,
|
| 563 |
+
'HAVE_UTIMES': 1,
|
| 564 |
+
'HAVE_UTIME_H': 1,
|
| 565 |
+
'HAVE_UUID_CREATE': 0,
|
| 566 |
+
'HAVE_UUID_ENC_BE': 0,
|
| 567 |
+
'HAVE_UUID_GENERATE_TIME_SAFE': 1,
|
| 568 |
+
'HAVE_UUID_H': 0,
|
| 569 |
+
'HAVE_UUID_UUID_H': 1,
|
| 570 |
+
'HAVE_WAIT3': 1,
|
| 571 |
+
'HAVE_WAIT4': 1,
|
| 572 |
+
'HAVE_WAITID': 1,
|
| 573 |
+
'HAVE_WAITPID': 1,
|
| 574 |
+
'HAVE_WCHAR_H': 1,
|
| 575 |
+
'HAVE_WCSCOLL': 1,
|
| 576 |
+
'HAVE_WCSFTIME': 1,
|
| 577 |
+
'HAVE_WCSXFRM': 1,
|
| 578 |
+
'HAVE_WMEMCMP': 1,
|
| 579 |
+
'HAVE_WORKING_TZSET': 1,
|
| 580 |
+
'HAVE_WRITEV': 1,
|
| 581 |
+
'HAVE_X509_VERIFY_PARAM_SET1_HOST': 1,
|
| 582 |
+
'HAVE_ZLIB_COPY': 1,
|
| 583 |
+
'HAVE__GETPTY': 0,
|
| 584 |
+
'HOST_GNU_TYPE': 'x86_64-conda-linux-gnu',
|
| 585 |
+
'INCLDIRSTOMAKE': '/workspace/anaconda3/include '
|
| 586 |
+
'/workspace/anaconda3/include '
|
| 587 |
+
'/workspace/anaconda3/include/python3.8 '
|
| 588 |
+
'/workspace/anaconda3/include/python3.8',
|
| 589 |
+
'INCLUDEDIR': '/workspace/anaconda3/include',
|
| 590 |
+
'INCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 591 |
+
'INSTALL': '/usr/bin/install -c',
|
| 592 |
+
'INSTALL_DATA': '/usr/bin/install -c -m 644',
|
| 593 |
+
'INSTALL_PROGRAM': '/usr/bin/install -c',
|
| 594 |
+
'INSTALL_SCRIPT': '/usr/bin/install -c',
|
| 595 |
+
'INSTALL_SHARED': '/usr/bin/install -c -m 755',
|
| 596 |
+
'INSTSONAME': 'libpython3.8.a',
|
| 597 |
+
'IO_H': 'Modules/_io/_iomodule.h',
|
| 598 |
+
'IO_OBJS': '\\',
|
| 599 |
+
'LDCXXSHARED': 'x86_64-conda-linux-gnu-c++ -pthread -shared',
|
| 600 |
+
'LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 601 |
+
'-Wl,--disable-new-dtags -Wl,--gc-sections '
|
| 602 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 603 |
+
'-Wl,-rpath-link,/workspace/anaconda3/lib '
|
| 604 |
+
'-L/workspace/anaconda3/lib '
|
| 605 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 606 |
+
'-Wl,--disable-new-dtags -Wl,--gc-sections '
|
| 607 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 608 |
+
'-Wl,-rpath-link,/workspace/anaconda3/lib '
|
| 609 |
+
'-L/workspace/anaconda3/lib',
|
| 610 |
+
'LDLIBRARY': 'libpython3.8.a',
|
| 611 |
+
'LDLIBRARYDIR': '',
|
| 612 |
+
'LDSHARED': 'x86_64-conda-linux-gnu-gcc -pthread -shared -Wl,-O2 '
|
| 613 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 614 |
+
'-Wl,--disable-new-dtags -Wl,--gc-sections '
|
| 615 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 616 |
+
'-Wl,-rpath-link,/workspace/anaconda3/lib '
|
| 617 |
+
'-L/workspace/anaconda3/lib '
|
| 618 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 619 |
+
'-Wl,-z,now -Wl,--disable-new-dtags -Wl,--gc-sections '
|
| 620 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 621 |
+
'-Wl,-rpath-link,/workspace/anaconda3/lib '
|
| 622 |
+
'-L/workspace/anaconda3/lib',
|
| 623 |
+
'LDVERSION': '3.8',
|
| 624 |
+
'LIBC': '',
|
| 625 |
+
'LIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 626 |
+
'LIBDIR': '/workspace/anaconda3/lib',
|
| 627 |
+
'LIBFFI_INCLUDEDIR': '/workspace/anaconda3/include',
|
| 628 |
+
'LIBM': '-lm',
|
| 629 |
+
'LIBOBJDIR': 'Python/',
|
| 630 |
+
'LIBOBJS': '',
|
| 631 |
+
'LIBPC': '/workspace/anaconda3/lib/pkgconfig',
|
| 632 |
+
'LIBPL': '/workspace/anaconda3/lib/python3.8/config-3.8-x86_64-linux-gnu',
|
| 633 |
+
'LIBPYTHON': '',
|
| 634 |
+
'LIBRARY': 'libpython3.8.a',
|
| 635 |
+
'LIBRARY_OBJS': '\\',
|
| 636 |
+
'LIBRARY_OBJS_OMIT_FROZEN': '\\',
|
| 637 |
+
'LIBS': '-lcrypt -lpthread -ldl -lutil -lm',
|
| 638 |
+
'LIBSUBDIRS': 'tkinter tkinter/test tkinter/test/test_tkinter \\',
|
| 639 |
+
'LINKCC': 'x86_64-conda-linux-gnu-gcc -pthread',
|
| 640 |
+
'LINKFORSHARED': '-Xlinker -export-dynamic',
|
| 641 |
+
'LIPO_32BIT_FLAGS': '',
|
| 642 |
+
'LIPO_INTEL64_FLAGS': '',
|
| 643 |
+
'LLVM_PROF_ERR': 'no',
|
| 644 |
+
'LLVM_PROF_FILE': '',
|
| 645 |
+
'LLVM_PROF_MERGER': 'true',
|
| 646 |
+
'LN': 'ln',
|
| 647 |
+
'LOCALMODLIBS': '',
|
| 648 |
+
'MACHDEP': 'linux',
|
| 649 |
+
'MACHDEP_OBJS': '',
|
| 650 |
+
'MACHDESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 651 |
+
'MACOSX_DEPLOYMENT_TARGET': '',
|
| 652 |
+
'MAINCC': 'x86_64-conda-linux-gnu-gcc -pthread',
|
| 653 |
+
'MAJOR_IN_MKDEV': 0,
|
| 654 |
+
'MAJOR_IN_SYSMACROS': 0,
|
| 655 |
+
'MAKESETUP': '/croot/python-split_1694437953337/work/Modules/makesetup',
|
| 656 |
+
'MANDIR': '/workspace/anaconda3/share/man',
|
| 657 |
+
'MKDIR_P': '/usr/bin/mkdir -p',
|
| 658 |
+
'MODBUILT_NAMES': 'posix errno pwd _sre _codecs _weakref _functools '
|
| 659 |
+
'_operator _collections _abc itertools atexit _signal '
|
| 660 |
+
'_stat time _thread _locale _io faulthandler '
|
| 661 |
+
'_tracemalloc _symtable xxsubtype',
|
| 662 |
+
'MODDISABLED_NAMES': '',
|
| 663 |
+
'MODLIBS': '',
|
| 664 |
+
'MODOBJS': 'Modules/posixmodule.o Modules/errnomodule.o '
|
| 665 |
+
'Modules/pwdmodule.o Modules/_sre.o Modules/_codecsmodule.o '
|
| 666 |
+
'Modules/_weakref.o Modules/_functoolsmodule.o '
|
| 667 |
+
'Modules/_operator.o Modules/_collectionsmodule.o '
|
| 668 |
+
'Modules/_abc.o Modules/itertoolsmodule.o '
|
| 669 |
+
'Modules/atexitmodule.o Modules/signalmodule.o Modules/_stat.o '
|
| 670 |
+
'Modules/timemodule.o Modules/_threadmodule.o '
|
| 671 |
+
'Modules/_localemodule.o Modules/_iomodule.o Modules/iobase.o '
|
| 672 |
+
'Modules/fileio.o Modules/bytesio.o Modules/bufferedio.o '
|
| 673 |
+
'Modules/textio.o Modules/stringio.o Modules/faulthandler.o '
|
| 674 |
+
'Modules/_tracemalloc.o Modules/hashtable.o '
|
| 675 |
+
'Modules/symtablemodule.o Modules/xxsubtype.o',
|
| 676 |
+
'MODULE_OBJS': '\\',
|
| 677 |
+
'MULTIARCH': 'x86_64-linux-gnu',
|
| 678 |
+
'MULTIARCH_CPPFLAGS': '-DMULTIARCH=\\"x86_64-linux-gnu\\"',
|
| 679 |
+
'MVWDELCH_IS_EXPRESSION': 1,
|
| 680 |
+
'NO_AS_NEEDED': '-Wl,--no-as-needed',
|
| 681 |
+
'OBJECT_OBJS': '\\',
|
| 682 |
+
'OPENSSL_INCLUDES': '-I/workspace/anaconda3/include',
|
| 683 |
+
'OPENSSL_LDFLAGS': '-L/workspace/anaconda3/lib',
|
| 684 |
+
'OPENSSL_LIBS': '-lssl -lcrypto',
|
| 685 |
+
'OPT': '-DNDEBUG -fwrapv -O2 -Wall',
|
| 686 |
+
'OTHER_LIBTOOL_OPT': '',
|
| 687 |
+
'PACKAGE_BUGREPORT': 0,
|
| 688 |
+
'PACKAGE_NAME': 0,
|
| 689 |
+
'PACKAGE_STRING': 0,
|
| 690 |
+
'PACKAGE_TARNAME': 0,
|
| 691 |
+
'PACKAGE_URL': 0,
|
| 692 |
+
'PACKAGE_VERSION': 0,
|
| 693 |
+
'PARSER_HEADERS': '\\',
|
| 694 |
+
'PARSER_OBJS': '\\ Parser/myreadline.o Parser/parsetok.o Parser/tokenizer.o',
|
| 695 |
+
'PGO_PROF_GEN_FLAG': '-fprofile-generate',
|
| 696 |
+
'PGO_PROF_USE_FLAG': ' ',
|
| 697 |
+
'POBJS': '\\',
|
| 698 |
+
'POSIX_SEMAPHORES_NOT_ENABLED': 0,
|
| 699 |
+
'PROFILE_TASK': '-m test --pgo',
|
| 700 |
+
'PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT': 1,
|
| 701 |
+
'PTHREAD_SYSTEM_SCHED_SUPPORTED': 1,
|
| 702 |
+
'PURIFY': '',
|
| 703 |
+
'PY3LIBRARY': '',
|
| 704 |
+
'PYLONG_BITS_IN_DIGIT': 0,
|
| 705 |
+
'PYTHON': 'python',
|
| 706 |
+
'PYTHONFRAMEWORK': '',
|
| 707 |
+
'PYTHONFRAMEWORKDIR': 'no-framework',
|
| 708 |
+
'PYTHONFRAMEWORKINSTALLDIR': '',
|
| 709 |
+
'PYTHONFRAMEWORKPREFIX': '',
|
| 710 |
+
'PYTHONPATH': '',
|
| 711 |
+
'PYTHON_FOR_BUILD': './python -E',
|
| 712 |
+
'PYTHON_FOR_REGEN': 'python3',
|
| 713 |
+
'PYTHON_HEADERS': '\\',
|
| 714 |
+
'PYTHON_OBJS': '\\',
|
| 715 |
+
'PY_BUILD_ENVIRON': '',
|
| 716 |
+
'PY_BUILTIN_MODULE_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG '
|
| 717 |
+
'-fwrapv -O2 -Wall -march=nocona -mtune=haswell '
|
| 718 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong '
|
| 719 |
+
'-fno-plt -O2 -ffunction-sections -pipe -isystem '
|
| 720 |
+
'/workspace/anaconda3/include '
|
| 721 |
+
'-fdebug-prefix-map=/croot/python-split_1694437953337/work=/usr/local/src/conda/python-3.8.18 '
|
| 722 |
+
'-fdebug-prefix-map=/workspace/anaconda3=/usr/local/src/conda-prefix '
|
| 723 |
+
' '
|
| 724 |
+
' -march=nocona '
|
| 725 |
+
'-mtune=haswell -ftree-vectorize -fPIC '
|
| 726 |
+
'-fstack-protector-strong -fno-plt -O2 '
|
| 727 |
+
'-ffunction-sections -pipe -isystem '
|
| 728 |
+
'/workspace/anaconda3/include '
|
| 729 |
+
'-fdebug-prefix-map=/croot/python-split_1694437953337/work=/usr/local/src/conda/python-3.8.18 '
|
| 730 |
+
'-fdebug-prefix-map=/workspace/anaconda3=/usr/local/src/conda-prefix '
|
| 731 |
+
' '
|
| 732 |
+
' '
|
| 733 |
+
' '
|
| 734 |
+
' -g -std=c99 -Wextra '
|
| 735 |
+
'-Wno-unused-result -Wno-unused-parameter '
|
| 736 |
+
'-Wno-missing-field-initializers '
|
| 737 |
+
'-Werror=implicit-function-declaration '
|
| 738 |
+
' '
|
| 739 |
+
'-I/croot/python-split_1694437953337/work/Include/internal '
|
| 740 |
+
'-IObjects -IInclude -IPython -I. '
|
| 741 |
+
'-I/croot/python-split_1694437953337/work/Include '
|
| 742 |
+
'-DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem '
|
| 743 |
+
'/workspace/anaconda3/include '
|
| 744 |
+
'-I/workspace/anaconda3/include '
|
| 745 |
+
'-DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem '
|
| 746 |
+
'/workspace/anaconda3/include '
|
| 747 |
+
'-I/workspace/anaconda3/include '
|
| 748 |
+
'-DPy_BUILD_CORE_BUILTIN',
|
| 749 |
+
'PY_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall '
|
| 750 |
+
'-march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 751 |
+
'-fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe '
|
| 752 |
+
'-isystem '
|
| 753 |
+
'/workspace/anaconda3/include '
|
| 754 |
+
'-fdebug-prefix-map=/croot/python-split_1694437953337/work=/usr/local/src/conda/python-3.8.18 '
|
| 755 |
+
'-fdebug-prefix-map=/workspace/anaconda3=/usr/local/src/conda-prefix '
|
| 756 |
+
' '
|
| 757 |
+
' -march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 758 |
+
'-fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe '
|
| 759 |
+
'-isystem '
|
| 760 |
+
'/workspace/anaconda3/include '
|
| 761 |
+
'-fdebug-prefix-map=/croot/python-split_1694437953337/work=/usr/local/src/conda/python-3.8.18 '
|
| 762 |
+
'-fdebug-prefix-map=/workspace/anaconda3=/usr/local/src/conda-prefix '
|
| 763 |
+
' '
|
| 764 |
+
'',
|
| 765 |
+
'PY_CFLAGS_NODIST': ' '
|
| 766 |
+
' -g -std=c99 -Wextra '
|
| 767 |
+
'-Wno-unused-result -Wno-unused-parameter '
|
| 768 |
+
'-Wno-missing-field-initializers '
|
| 769 |
+
'-Werror=implicit-function-declaration '
|
| 770 |
+
' '
|
| 771 |
+
'-I/croot/python-split_1694437953337/work/Include/internal',
|
| 772 |
+
'PY_COERCE_C_LOCALE': 1,
|
| 773 |
+
'PY_CORE_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 '
|
| 774 |
+
'-Wall -march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 775 |
+
'-fstack-protector-strong -fno-plt -O2 -ffunction-sections '
|
| 776 |
+
'-pipe -isystem '
|
| 777 |
+
'/workspace/anaconda3/include '
|
| 778 |
+
'-fdebug-prefix-map=/croot/python-split_1694437953337/work=/usr/local/src/conda/python-3.8.18 '
|
| 779 |
+
'-fdebug-prefix-map=/workspace/anaconda3=/usr/local/src/conda-prefix '
|
| 780 |
+
' '
|
| 781 |
+
' -march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 782 |
+
'-fstack-protector-strong -fno-plt -O2 -ffunction-sections '
|
| 783 |
+
'-pipe -isystem '
|
| 784 |
+
'/workspace/anaconda3/include '
|
| 785 |
+
'-fdebug-prefix-map=/croot/python-split_1694437953337/work=/usr/local/src/conda/python-3.8.18 '
|
| 786 |
+
'-fdebug-prefix-map=/workspace/anaconda3=/usr/local/src/conda-prefix '
|
| 787 |
+
' '
|
| 788 |
+
' '
|
| 789 |
+
' -g -std=c99 -Wextra '
|
| 790 |
+
'-Wno-unused-result -Wno-unused-parameter '
|
| 791 |
+
'-Wno-missing-field-initializers '
|
| 792 |
+
'-Werror=implicit-function-declaration '
|
| 793 |
+
' '
|
| 794 |
+
'-I/croot/python-split_1694437953337/work/Include/internal '
|
| 795 |
+
'-IObjects -IInclude -IPython -I. '
|
| 796 |
+
'-I/croot/python-split_1694437953337/work/Include -DNDEBUG '
|
| 797 |
+
'-D_FORTIFY_SOURCE=2 -O2 -isystem '
|
| 798 |
+
'/workspace/anaconda3/include '
|
| 799 |
+
'-I/workspace/anaconda3/include '
|
| 800 |
+
'-DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem '
|
| 801 |
+
'/workspace/anaconda3/include '
|
| 802 |
+
'-I/workspace/anaconda3/include '
|
| 803 |
+
'-DPy_BUILD_CORE',
|
| 804 |
+
'PY_CORE_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 805 |
+
'-Wl,-z,now -Wl,--disable-new-dtags -Wl,--gc-sections '
|
| 806 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 807 |
+
'-Wl,-rpath-link,/workspace/anaconda3/lib '
|
| 808 |
+
'-L/workspace/anaconda3/lib '
|
| 809 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 810 |
+
'-Wl,-z,now -Wl,--disable-new-dtags -Wl,--gc-sections '
|
| 811 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 812 |
+
'-Wl,-rpath-link,/workspace/anaconda3/lib '
|
| 813 |
+
'-L/workspace/anaconda3/lib '
|
| 814 |
+
' '
|
| 815 |
+
' -g',
|
| 816 |
+
'PY_CPPFLAGS': '-IObjects -IInclude -IPython -I. '
|
| 817 |
+
'-I/croot/python-split_1694437953337/work/Include -DNDEBUG '
|
| 818 |
+
'-D_FORTIFY_SOURCE=2 -O2 -isystem '
|
| 819 |
+
'/workspace/anaconda3/include '
|
| 820 |
+
'-I/workspace/anaconda3/include '
|
| 821 |
+
'-DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem '
|
| 822 |
+
'/workspace/anaconda3/include '
|
| 823 |
+
'-I/workspace/anaconda3/include',
|
| 824 |
+
'PY_FORMAT_SIZE_T': '"z"',
|
| 825 |
+
'PY_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 826 |
+
'-Wl,-z,now -Wl,--disable-new-dtags -Wl,--gc-sections '
|
| 827 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 828 |
+
'-Wl,-rpath-link,/workspace/anaconda3/lib '
|
| 829 |
+
'-L/workspace/anaconda3/lib '
|
| 830 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 831 |
+
'-Wl,-z,now -Wl,--disable-new-dtags -Wl,--gc-sections '
|
| 832 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 833 |
+
'-Wl,-rpath-link,/workspace/anaconda3/lib '
|
| 834 |
+
'-L/workspace/anaconda3/lib',
|
| 835 |
+
'PY_LDFLAGS_NODIST': ' '
|
| 836 |
+
' -g',
|
| 837 |
+
'PY_SSL_DEFAULT_CIPHERS': 1,
|
| 838 |
+
'PY_SSL_DEFAULT_CIPHER_STRING': 0,
|
| 839 |
+
'PY_STDMODULE_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv '
|
| 840 |
+
'-O2 -Wall -march=nocona -mtune=haswell '
|
| 841 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong '
|
| 842 |
+
'-fno-plt -O2 -ffunction-sections -pipe -isystem '
|
| 843 |
+
'/workspace/anaconda3/include '
|
| 844 |
+
'-fdebug-prefix-map=/croot/python-split_1694437953337/work=/usr/local/src/conda/python-3.8.18 '
|
| 845 |
+
'-fdebug-prefix-map=/workspace/anaconda3=/usr/local/src/conda-prefix '
|
| 846 |
+
' '
|
| 847 |
+
' -march=nocona '
|
| 848 |
+
'-mtune=haswell -ftree-vectorize -fPIC '
|
| 849 |
+
'-fstack-protector-strong -fno-plt -O2 '
|
| 850 |
+
'-ffunction-sections -pipe -isystem '
|
| 851 |
+
'/workspace/anaconda3/include '
|
| 852 |
+
'-fdebug-prefix-map=/croot/python-split_1694437953337/work=/usr/local/src/conda/python-3.8.18 '
|
| 853 |
+
'-fdebug-prefix-map=/workspace/anaconda3=/usr/local/src/conda-prefix '
|
| 854 |
+
' '
|
| 855 |
+
' '
|
| 856 |
+
' -g -std=c99 '
|
| 857 |
+
'-Wextra -Wno-unused-result -Wno-unused-parameter '
|
| 858 |
+
'-Wno-missing-field-initializers '
|
| 859 |
+
'-Werror=implicit-function-declaration '
|
| 860 |
+
' '
|
| 861 |
+
'-I/croot/python-split_1694437953337/work/Include/internal '
|
| 862 |
+
'-IObjects -IInclude -IPython -I. '
|
| 863 |
+
'-I/croot/python-split_1694437953337/work/Include '
|
| 864 |
+
'-DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem '
|
| 865 |
+
'/workspace/anaconda3/include '
|
| 866 |
+
'-I/workspace/anaconda3/include '
|
| 867 |
+
'-DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem '
|
| 868 |
+
'/workspace/anaconda3/include '
|
| 869 |
+
'-I/workspace/anaconda3/include',
|
| 870 |
+
'Py_DEBUG': 0,
|
| 871 |
+
'Py_ENABLE_SHARED': 0,
|
| 872 |
+
'Py_HASH_ALGORITHM': 0,
|
| 873 |
+
'Py_TRACE_REFS': 0,
|
| 874 |
+
'QUICKTESTOPTS': '-x test_subprocess test_io test_lib2to3 \\',
|
| 875 |
+
'READELF': 'x86_64-conda-linux-gnu-readelf',
|
| 876 |
+
'RESSRCDIR': 'Mac/Resources/framework',
|
| 877 |
+
'RETSIGTYPE': 'void',
|
| 878 |
+
'RUNSHARED': '',
|
| 879 |
+
'SCRIPTDIR': '/workspace/anaconda3/lib',
|
| 880 |
+
'SETPGRP_HAVE_ARG': 0,
|
| 881 |
+
'SGI_ABI': '@SGI_ABI@',
|
| 882 |
+
'SHELL': '/bin/sh',
|
| 883 |
+
'SHLIBS': '-lcrypt -lpthread -ldl -lutil -lm',
|
| 884 |
+
'SHLIB_SUFFIX': '.so',
|
| 885 |
+
'SHM_NEEDS_LIBRT': 1,
|
| 886 |
+
'SIGNED_RIGHT_SHIFT_ZERO_FILLS': 0,
|
| 887 |
+
'SITEPATH': '',
|
| 888 |
+
'SIZEOF_DOUBLE': 8,
|
| 889 |
+
'SIZEOF_FLOAT': 4,
|
| 890 |
+
'SIZEOF_FPOS_T': 16,
|
| 891 |
+
'SIZEOF_INT': 4,
|
| 892 |
+
'SIZEOF_LONG': 8,
|
| 893 |
+
'SIZEOF_LONG_DOUBLE': 16,
|
| 894 |
+
'SIZEOF_LONG_LONG': 8,
|
| 895 |
+
'SIZEOF_OFF_T': 8,
|
| 896 |
+
'SIZEOF_PID_T': 4,
|
| 897 |
+
'SIZEOF_PTHREAD_KEY_T': 4,
|
| 898 |
+
'SIZEOF_PTHREAD_T': 8,
|
| 899 |
+
'SIZEOF_SHORT': 2,
|
| 900 |
+
'SIZEOF_SIZE_T': 8,
|
| 901 |
+
'SIZEOF_TIME_T': 8,
|
| 902 |
+
'SIZEOF_UINTPTR_T': 8,
|
| 903 |
+
'SIZEOF_VOID_P': 8,
|
| 904 |
+
'SIZEOF_WCHAR_T': 4,
|
| 905 |
+
'SIZEOF__BOOL': 1,
|
| 906 |
+
'SOABI': 'cpython-38-x86_64-linux-gnu',
|
| 907 |
+
'SRCDIRS': 'Parser Objects Python Modules Modules/_io Programs',
|
| 908 |
+
'SRC_GDB_HOOKS': '/croot/python-split_1694437953337/work/Tools/gdb/libpython.py',
|
| 909 |
+
'STDC_HEADERS': 1,
|
| 910 |
+
'STRICT_SYSV_CURSES': "/* Don't use ncurses extensions */",
|
| 911 |
+
'STRIPFLAG': '-s',
|
| 912 |
+
'SUBDIRS': '',
|
| 913 |
+
'SUBDIRSTOO': 'Include Lib Misc',
|
| 914 |
+
'SYSLIBS': '-lm',
|
| 915 |
+
'SYS_SELECT_WITH_SYS_TIME': 1,
|
| 916 |
+
'TCLTK_INCLUDES': '-I/workspace/anaconda3/include',
|
| 917 |
+
'TCLTK_LIBS': '-L/workspace/anaconda3/lib '
|
| 918 |
+
'-ltcl8.6 -ltk8.6',
|
| 919 |
+
'TESTOPTS': '',
|
| 920 |
+
'TESTPATH': '',
|
| 921 |
+
'TESTPYTHON': './python',
|
| 922 |
+
'TESTPYTHONOPTS': '',
|
| 923 |
+
'TESTRUNNER': './python '
|
| 924 |
+
'/croot/python-split_1694437953337/work/Tools/scripts/run_tests.py',
|
| 925 |
+
'TESTTIMEOUT': 1200,
|
| 926 |
+
'TIMEMODULE_LIB': 0,
|
| 927 |
+
'TIME_WITH_SYS_TIME': 1,
|
| 928 |
+
'TM_IN_SYS_TIME': 0,
|
| 929 |
+
'UNICODE_DEPS': '\\',
|
| 930 |
+
'UNIVERSALSDK': '',
|
| 931 |
+
'UPDATE_FILE': 'python3 '
|
| 932 |
+
'/croot/python-split_1694437953337/work/Tools/scripts/update_file.py',
|
| 933 |
+
'USE_COMPUTED_GOTOS': 1,
|
| 934 |
+
'VERSION': '3.8',
|
| 935 |
+
'VPATH': '/croot/python-split_1694437953337/work',
|
| 936 |
+
'WINDOW_HAS_FLAGS': 1,
|
| 937 |
+
'WITH_DECIMAL_CONTEXTVAR': 1,
|
| 938 |
+
'WITH_DOC_STRINGS': 1,
|
| 939 |
+
'WITH_DTRACE': 0,
|
| 940 |
+
'WITH_DYLD': 0,
|
| 941 |
+
'WITH_LIBINTL': 0,
|
| 942 |
+
'WITH_NEXT_FRAMEWORK': 0,
|
| 943 |
+
'WITH_PYMALLOC': 1,
|
| 944 |
+
'WITH_VALGRIND': 0,
|
| 945 |
+
'X87_DOUBLE_ROUNDING': 0,
|
| 946 |
+
'XMLLIBSUBDIRS': 'xml xml/dom xml/etree xml/parsers xml/sax',
|
| 947 |
+
'abs_builddir': '/croot/python-split_1694437953337/work/build-static',
|
| 948 |
+
'abs_srcdir': '/croot/python-split_1694437953337/work',
|
| 949 |
+
'datarootdir': '/workspace/anaconda3/share',
|
| 950 |
+
'exec_prefix': '/workspace/anaconda3',
|
| 951 |
+
'prefix': '/workspace/anaconda3',
|
| 952 |
+
'srcdir': '/croot/python-split_1694437953337/work'}
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata_aarch64_conda_linux_gnu.py
ADDED
|
@@ -0,0 +1,805 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# system configuration generated and used by the sysconfig module
|
| 2 |
+
build_time_vars = {'ABIFLAGS': '',
|
| 3 |
+
'AC_APPLE_UNIVERSAL_BUILD': 0,
|
| 4 |
+
'AIX_GENUINE_CPLUSPLUS': 0,
|
| 5 |
+
'ANDROID_API_LEVEL': 0,
|
| 6 |
+
'AR': 'aarch64-conda-linux-gnu-ar',
|
| 7 |
+
'ARFLAGS': 'rc',
|
| 8 |
+
'BASECFLAGS': '-Wno-unused-result -Wsign-compare',
|
| 9 |
+
'BASECPPFLAGS': '-IObjects -IInclude -IPython',
|
| 10 |
+
'BASEMODLIBS': '',
|
| 11 |
+
'BINDIR': '/workspace/anaconda3/bin',
|
| 12 |
+
'BINLIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 13 |
+
'BLDLIBRARY': 'libpython3.8.a',
|
| 14 |
+
'BLDSHARED': 'aarch64-conda-linux-gnu-gcc -pthread -shared -Wl,-O2 '
|
| 15 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 16 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 17 |
+
'-L/workspace/anaconda3/lib '
|
| 18 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 19 |
+
'-Wl,-z,now '
|
| 20 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 21 |
+
'-L/workspace/anaconda3/lib '
|
| 22 |
+
' '
|
| 23 |
+
'',
|
| 24 |
+
'BUILDEXE': '',
|
| 25 |
+
'BUILDPYTHON': 'python',
|
| 26 |
+
'BUILD_GNU_TYPE': 'aarch64-conda-linux-gnu',
|
| 27 |
+
'BYTESTR_DEPS': '\\',
|
| 28 |
+
'CC': 'aarch64-conda-linux-gnu-gcc -pthread',
|
| 29 |
+
'CCSHARED': '-fPIC',
|
| 30 |
+
'CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall '
|
| 31 |
+
'-Wstrict-prototypes -ftree-vectorize '
|
| 32 |
+
'-fPIC -fstack-protector-strong -fno-plt -O2 -pipe '
|
| 33 |
+
'-ftree-vectorize -fPIC '
|
| 34 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 35 |
+
'',
|
| 36 |
+
'CFLAGSFORSHARED': '',
|
| 37 |
+
'CFLAGS_ALIASING': '',
|
| 38 |
+
'CONFIGFILES': 'configure configure.ac acconfig.h pyconfig.h.in '
|
| 39 |
+
'Makefile.pre.in',
|
| 40 |
+
'CONFIGURE_CFLAGS': '-ftree-vectorize -fPIC '
|
| 41 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe ',
|
| 42 |
+
'CONFIGURE_CFLAGS_NODIST': '-std=c99 -Wextra -Wno-unused-result '
|
| 43 |
+
'-Wno-unused-parameter '
|
| 44 |
+
'-Wno-missing-field-initializers',
|
| 45 |
+
'CONFIGURE_CPPFLAGS': '-D_FORTIFY_SOURCE=2 -O2 '
|
| 46 |
+
'-I/workspace/anaconda3/include',
|
| 47 |
+
'CONFIGURE_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 48 |
+
'-Wl,-z,now '
|
| 49 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 50 |
+
'-L/workspace/anaconda3/lib',
|
| 51 |
+
'CONFIG_ARGS': "'--prefix=/workspace/anaconda3' "
|
| 52 |
+
"'--build=aarch64-conda-linux-gnu' "
|
| 53 |
+
"'--host=aarch64-conda-linux-gnu' '--enable-ipv6' "
|
| 54 |
+
"'--with-ensurepip=no' '--with-computed-gotos' "
|
| 55 |
+
"'--with-system-ffi' '--enable-loadable-sqlite-extensions' "
|
| 56 |
+
"'--with-tcltk-includes=-I/workspace/anaconda3/include' "
|
| 57 |
+
"'--with-tcltk-libs=-L/workspace/anaconda3/lib "
|
| 58 |
+
"-ltcl8.6 -ltk8.6' '--enable-optimizations' '--with-lto' "
|
| 59 |
+
"'--disable-shared' "
|
| 60 |
+
"'build_alias=aarch64-conda-linux-gnu' "
|
| 61 |
+
"'host_alias=aarch64-conda-linux-gnu' "
|
| 62 |
+
"'CC=aarch64-conda-linux-gnu-gcc' "
|
| 63 |
+
"'CFLAGS=-ftree-vectorize -fPIC "
|
| 64 |
+
'-fstack-protector-strong -fno-plt -O2 '
|
| 65 |
+
'-pipe '
|
| 66 |
+
' '
|
| 67 |
+
" ' 'LDFLAGS=-Wl,-O2 "
|
| 68 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 69 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 70 |
+
"-L/workspace/anaconda3/lib' "
|
| 71 |
+
"'CPPFLAGS=-D_FORTIFY_SOURCE=2 -O2 "
|
| 72 |
+
"-I/workspace/anaconda3/include' "
|
| 73 |
+
"'CPP=/workspace/anaconda3/bin/aarch64-conda-linux-gnu-cpp' "
|
| 74 |
+
"'PKG_CONFIG_PATH=/workspace/anaconda3/lib/pkgconfig'",
|
| 75 |
+
'CONFINCLUDEDIR': '/workspace/anaconda3/include',
|
| 76 |
+
'CONFINCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 77 |
+
'COREPYTHONPATH': ':',
|
| 78 |
+
'COVERAGE_INFO': '/opt/conda/conda-bld/python_1512347718438/work/build-static/coverage.info',
|
| 79 |
+
'COVERAGE_REPORT': '/opt/conda/conda-bld/python_1512347718438/work/build-static/lcov-report',
|
| 80 |
+
'COVERAGE_REPORT_OPTIONS': '--no-branch-coverage --title "CPython lcov '
|
| 81 |
+
'report"',
|
| 82 |
+
'CPPFLAGS': '-IObjects -IInclude -IPython -I. '
|
| 83 |
+
'-I/opt/conda/conda-bld/python_1512347718438/work/Include '
|
| 84 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 85 |
+
'-I/workspace/anaconda3/include '
|
| 86 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 87 |
+
'-I/workspace/anaconda3/include',
|
| 88 |
+
'CXX': 'aarch64-conda-linux-gnu-c++ -pthread',
|
| 89 |
+
'DESTDIRS': '/workspace/anaconda3 '
|
| 90 |
+
'/workspace/anaconda3/lib '
|
| 91 |
+
'/workspace/anaconda3/lib/python3.8 '
|
| 92 |
+
'/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 93 |
+
'DESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 94 |
+
'DESTPATH': '',
|
| 95 |
+
'DESTSHARED': '/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 96 |
+
'DFLAGS': '',
|
| 97 |
+
'DIRMODE': 755,
|
| 98 |
+
'DIST': 'README ChangeLog configure configure.ac acconfig.h pyconfig.h.in '
|
| 99 |
+
'Makefile.pre.in Include Lib Misc Ext-dummy',
|
| 100 |
+
'DISTDIRS': 'Include Lib Misc Ext-dummy',
|
| 101 |
+
'DISTFILES': 'README ChangeLog configure configure.ac acconfig.h '
|
| 102 |
+
'pyconfig.h.in Makefile.pre.in',
|
| 103 |
+
'DLINCLDIR': '.',
|
| 104 |
+
'DLLLIBRARY': '',
|
| 105 |
+
'DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754': 0,
|
| 106 |
+
'DOUBLE_IS_BIG_ENDIAN_IEEE754': 0,
|
| 107 |
+
'DOUBLE_IS_LITTLE_ENDIAN_IEEE754': 1,
|
| 108 |
+
'DTRACE': '',
|
| 109 |
+
'DTRACE_DEPS': '\\',
|
| 110 |
+
'DTRACE_HEADERS': '',
|
| 111 |
+
'DTRACE_OBJS': '',
|
| 112 |
+
'DYNLOADFILE': 'dynload_shlib.o',
|
| 113 |
+
'ENABLE_IPV6': 1,
|
| 114 |
+
'ENSUREPIP': 'no',
|
| 115 |
+
'EXE': '',
|
| 116 |
+
'EXEMODE': 755,
|
| 117 |
+
'EXTRAMACHDEPPATH': '',
|
| 118 |
+
'EXTRATESTOPTS': '',
|
| 119 |
+
'EXT_SUFFIX': '.cpython-38-aarch64-linux-gnu.so',
|
| 120 |
+
'FILEMODE': 644,
|
| 121 |
+
'FLOCK_NEEDS_LIBBSD': 0,
|
| 122 |
+
'GETPGRP_HAVE_ARG': 0,
|
| 123 |
+
'GETTIMEOFDAY_NO_TZ': 0,
|
| 124 |
+
'GITBRANCH': '',
|
| 125 |
+
'GITTAG': '',
|
| 126 |
+
'GITVERSION': '',
|
| 127 |
+
'GNULD': 'yes',
|
| 128 |
+
'HAVE_ACCEPT4': 1,
|
| 129 |
+
'HAVE_ACOSH': 1,
|
| 130 |
+
'HAVE_ADDRINFO': 1,
|
| 131 |
+
'HAVE_ALARM': 1,
|
| 132 |
+
'HAVE_ALIGNED_REQUIRED': 1,
|
| 133 |
+
'HAVE_ALLOCA_H': 1,
|
| 134 |
+
'HAVE_ALTZONE': 0,
|
| 135 |
+
'HAVE_ASINH': 1,
|
| 136 |
+
'HAVE_ASM_TYPES_H': 1,
|
| 137 |
+
'HAVE_ATANH': 1,
|
| 138 |
+
'HAVE_BIND_TEXTDOMAIN_CODESET': 1,
|
| 139 |
+
'HAVE_BLUETOOTH_BLUETOOTH_H': 0,
|
| 140 |
+
'HAVE_BLUETOOTH_H': 0,
|
| 141 |
+
'HAVE_BROKEN_MBSTOWCS': 0,
|
| 142 |
+
'HAVE_BROKEN_NICE': 0,
|
| 143 |
+
'HAVE_BROKEN_PIPE_BUF': 0,
|
| 144 |
+
'HAVE_BROKEN_POLL': 0,
|
| 145 |
+
'HAVE_BROKEN_POSIX_SEMAPHORES': 0,
|
| 146 |
+
'HAVE_BROKEN_PTHREAD_SIGMASK': 0,
|
| 147 |
+
'HAVE_BROKEN_SEM_GETVALUE': 1,
|
| 148 |
+
'HAVE_BROKEN_UNSETENV': 0,
|
| 149 |
+
'HAVE_BUILTIN_ATOMIC': 1,
|
| 150 |
+
'HAVE_CHFLAGS': 0,
|
| 151 |
+
'HAVE_CHOWN': 1,
|
| 152 |
+
'HAVE_CHROOT': 1,
|
| 153 |
+
'HAVE_CLOCK': 1,
|
| 154 |
+
'HAVE_CLOCK_GETRES': 1,
|
| 155 |
+
'HAVE_CLOCK_GETTIME': 1,
|
| 156 |
+
'HAVE_CLOCK_SETTIME': 1,
|
| 157 |
+
'HAVE_COMPUTED_GOTOS': 1,
|
| 158 |
+
'HAVE_CONFSTR': 1,
|
| 159 |
+
'HAVE_CONIO_H': 0,
|
| 160 |
+
'HAVE_COPYSIGN': 1,
|
| 161 |
+
'HAVE_CTERMID': 1,
|
| 162 |
+
'HAVE_CTERMID_R': 0,
|
| 163 |
+
'HAVE_CURSES_FILTER': 1,
|
| 164 |
+
'HAVE_CURSES_H': 1,
|
| 165 |
+
'HAVE_CURSES_HAS_KEY': 1,
|
| 166 |
+
'HAVE_CURSES_IMMEDOK': 1,
|
| 167 |
+
'HAVE_CURSES_IS_PAD': 1,
|
| 168 |
+
'HAVE_CURSES_IS_TERM_RESIZED': 1,
|
| 169 |
+
'HAVE_CURSES_RESIZETERM': 1,
|
| 170 |
+
'HAVE_CURSES_RESIZE_TERM': 1,
|
| 171 |
+
'HAVE_CURSES_SYNCOK': 1,
|
| 172 |
+
'HAVE_CURSES_TYPEAHEAD': 1,
|
| 173 |
+
'HAVE_CURSES_USE_ENV': 1,
|
| 174 |
+
'HAVE_CURSES_WCHGAT': 1,
|
| 175 |
+
'HAVE_DECL_ISFINITE': 1,
|
| 176 |
+
'HAVE_DECL_ISINF': 1,
|
| 177 |
+
'HAVE_DECL_ISNAN': 1,
|
| 178 |
+
'HAVE_DECL_RTLD_DEEPBIND': 1,
|
| 179 |
+
'HAVE_DECL_RTLD_GLOBAL': 1,
|
| 180 |
+
'HAVE_DECL_RTLD_LAZY': 1,
|
| 181 |
+
'HAVE_DECL_RTLD_LOCAL': 1,
|
| 182 |
+
'HAVE_DECL_RTLD_MEMBER': 0,
|
| 183 |
+
'HAVE_DECL_RTLD_NODELETE': 1,
|
| 184 |
+
'HAVE_DECL_RTLD_NOLOAD': 1,
|
| 185 |
+
'HAVE_DECL_RTLD_NOW': 1,
|
| 186 |
+
'HAVE_DECL_TZNAME': 0,
|
| 187 |
+
'HAVE_DEVICE_MACROS': 1,
|
| 188 |
+
'HAVE_DEV_PTC': 1,
|
| 189 |
+
'HAVE_DEV_PTMX': 1,
|
| 190 |
+
'HAVE_DIRECT_H': 0,
|
| 191 |
+
'HAVE_DIRENT_D_TYPE': 1,
|
| 192 |
+
'HAVE_DIRENT_H': 1,
|
| 193 |
+
'HAVE_DIRFD': 1,
|
| 194 |
+
'HAVE_DLFCN_H': 1,
|
| 195 |
+
'HAVE_DLOPEN': 1,
|
| 196 |
+
'HAVE_DUP2': 1,
|
| 197 |
+
'HAVE_DUP3': 1,
|
| 198 |
+
'HAVE_DYNAMIC_LOADING': 1,
|
| 199 |
+
'HAVE_ENDIAN_H': 1,
|
| 200 |
+
'HAVE_EPOLL': 1,
|
| 201 |
+
'HAVE_EPOLL_CREATE1': 1,
|
| 202 |
+
'HAVE_ERF': 1,
|
| 203 |
+
'HAVE_ERFC': 1,
|
| 204 |
+
'HAVE_ERRNO_H': 1,
|
| 205 |
+
'HAVE_EXECV': 1,
|
| 206 |
+
'HAVE_EXPM1': 1,
|
| 207 |
+
'HAVE_FACCESSAT': 1,
|
| 208 |
+
'HAVE_FCHDIR': 1,
|
| 209 |
+
'HAVE_FCHMOD': 1,
|
| 210 |
+
'HAVE_FCHMODAT': 1,
|
| 211 |
+
'HAVE_FCHOWN': 1,
|
| 212 |
+
'HAVE_FCHOWNAT': 1,
|
| 213 |
+
'HAVE_FCNTL_H': 1,
|
| 214 |
+
'HAVE_FDATASYNC': 1,
|
| 215 |
+
'HAVE_FDOPENDIR': 1,
|
| 216 |
+
'HAVE_FEXECVE': 1,
|
| 217 |
+
'HAVE_FINITE': 1,
|
| 218 |
+
'HAVE_FLOCK': 1,
|
| 219 |
+
'HAVE_FORK': 1,
|
| 220 |
+
'HAVE_FORKPTY': 1,
|
| 221 |
+
'HAVE_FPATHCONF': 1,
|
| 222 |
+
'HAVE_FSEEK64': 0,
|
| 223 |
+
'HAVE_FSEEKO': 1,
|
| 224 |
+
'HAVE_FSTATAT': 1,
|
| 225 |
+
'HAVE_FSTATVFS': 1,
|
| 226 |
+
'HAVE_FSYNC': 1,
|
| 227 |
+
'HAVE_FTELL64': 0,
|
| 228 |
+
'HAVE_FTELLO': 1,
|
| 229 |
+
'HAVE_FTIME': 1,
|
| 230 |
+
'HAVE_FTRUNCATE': 1,
|
| 231 |
+
'HAVE_FUTIMENS': 1,
|
| 232 |
+
'HAVE_FUTIMES': 1,
|
| 233 |
+
'HAVE_FUTIMESAT': 1,
|
| 234 |
+
'HAVE_GAI_STRERROR': 1,
|
| 235 |
+
'HAVE_GAMMA': 1,
|
| 236 |
+
'HAVE_GCC_ASM_FOR_MC68881': 0,
|
| 237 |
+
'HAVE_GCC_ASM_FOR_X64': 0,
|
| 238 |
+
'HAVE_GCC_ASM_FOR_X87': 0,
|
| 239 |
+
'HAVE_GCC_UINT128_T': 1,
|
| 240 |
+
'HAVE_GETADDRINFO': 1,
|
| 241 |
+
'HAVE_GETC_UNLOCKED': 1,
|
| 242 |
+
'HAVE_GETENTROPY': 0,
|
| 243 |
+
'HAVE_GETGROUPLIST': 1,
|
| 244 |
+
'HAVE_GETGROUPS': 1,
|
| 245 |
+
'HAVE_GETHOSTBYNAME': 0,
|
| 246 |
+
'HAVE_GETHOSTBYNAME_R': 1,
|
| 247 |
+
'HAVE_GETHOSTBYNAME_R_3_ARG': 0,
|
| 248 |
+
'HAVE_GETHOSTBYNAME_R_5_ARG': 0,
|
| 249 |
+
'HAVE_GETHOSTBYNAME_R_6_ARG': 1,
|
| 250 |
+
'HAVE_GETITIMER': 1,
|
| 251 |
+
'HAVE_GETLOADAVG': 1,
|
| 252 |
+
'HAVE_GETLOGIN': 1,
|
| 253 |
+
'HAVE_GETNAMEINFO': 1,
|
| 254 |
+
'HAVE_GETPAGESIZE': 1,
|
| 255 |
+
'HAVE_GETPEERNAME': 1,
|
| 256 |
+
'HAVE_GETPGID': 1,
|
| 257 |
+
'HAVE_GETPGRP': 1,
|
| 258 |
+
'HAVE_GETPID': 1,
|
| 259 |
+
'HAVE_GETPRIORITY': 1,
|
| 260 |
+
'HAVE_GETPWENT': 1,
|
| 261 |
+
'HAVE_GETRANDOM': 0,
|
| 262 |
+
'HAVE_GETRANDOM_SYSCALL': 0,
|
| 263 |
+
'HAVE_GETRESGID': 1,
|
| 264 |
+
'HAVE_GETRESUID': 1,
|
| 265 |
+
'HAVE_GETSID': 1,
|
| 266 |
+
'HAVE_GETSPENT': 1,
|
| 267 |
+
'HAVE_GETSPNAM': 1,
|
| 268 |
+
'HAVE_GETTIMEOFDAY': 1,
|
| 269 |
+
'HAVE_GETWD': 1,
|
| 270 |
+
'HAVE_GLIBC_MEMMOVE_BUG': 0,
|
| 271 |
+
'HAVE_GRP_H': 1,
|
| 272 |
+
'HAVE_HSTRERROR': 1,
|
| 273 |
+
'HAVE_HTOLE64': 1,
|
| 274 |
+
'HAVE_HYPOT': 1,
|
| 275 |
+
'HAVE_IEEEFP_H': 0,
|
| 276 |
+
'HAVE_IF_NAMEINDEX': 1,
|
| 277 |
+
'HAVE_INET_ATON': 1,
|
| 278 |
+
'HAVE_INET_PTON': 1,
|
| 279 |
+
'HAVE_INITGROUPS': 1,
|
| 280 |
+
'HAVE_INTTYPES_H': 1,
|
| 281 |
+
'HAVE_IO_H': 0,
|
| 282 |
+
'HAVE_IPA_PURE_CONST_BUG': 0,
|
| 283 |
+
'HAVE_KILL': 1,
|
| 284 |
+
'HAVE_KILLPG': 1,
|
| 285 |
+
'HAVE_KQUEUE': 0,
|
| 286 |
+
'HAVE_LANGINFO_H': 1,
|
| 287 |
+
'HAVE_LARGEFILE_SUPPORT': 0,
|
| 288 |
+
'HAVE_LCHFLAGS': 0,
|
| 289 |
+
'HAVE_LCHMOD': 0,
|
| 290 |
+
'HAVE_LCHOWN': 1,
|
| 291 |
+
'HAVE_LGAMMA': 1,
|
| 292 |
+
'HAVE_LIBDL': 1,
|
| 293 |
+
'HAVE_LIBDLD': 0,
|
| 294 |
+
'HAVE_LIBIEEE': 0,
|
| 295 |
+
'HAVE_LIBINTL_H': 1,
|
| 296 |
+
'HAVE_LIBREADLINE': 1,
|
| 297 |
+
'HAVE_LIBRESOLV': 0,
|
| 298 |
+
'HAVE_LIBSENDFILE': 0,
|
| 299 |
+
'HAVE_LIBUTIL_H': 0,
|
| 300 |
+
'HAVE_LINK': 1,
|
| 301 |
+
'HAVE_LINKAT': 1,
|
| 302 |
+
'HAVE_LINUX_CAN_BCM_H': 1,
|
| 303 |
+
'HAVE_LINUX_CAN_H': 1,
|
| 304 |
+
'HAVE_LINUX_CAN_RAW_FD_FRAMES': 1,
|
| 305 |
+
'HAVE_LINUX_CAN_RAW_H': 1,
|
| 306 |
+
'HAVE_LINUX_NETLINK_H': 1,
|
| 307 |
+
'HAVE_LINUX_RANDOM_H': 1,
|
| 308 |
+
'HAVE_LINUX_TIPC_H': 1,
|
| 309 |
+
'HAVE_LINUX_VM_SOCKETS_H': 0,
|
| 310 |
+
'HAVE_LOCKF': 1,
|
| 311 |
+
'HAVE_LOG1P': 1,
|
| 312 |
+
'HAVE_LOG2': 1,
|
| 313 |
+
'HAVE_LONG_DOUBLE': 1,
|
| 314 |
+
'HAVE_LSTAT': 1,
|
| 315 |
+
'HAVE_LUTIMES': 1,
|
| 316 |
+
'HAVE_MAKEDEV': 1,
|
| 317 |
+
'HAVE_MBRTOWC': 1,
|
| 318 |
+
'HAVE_MEMORY_H': 1,
|
| 319 |
+
'HAVE_MEMRCHR': 1,
|
| 320 |
+
'HAVE_MKDIRAT': 1,
|
| 321 |
+
'HAVE_MKFIFO': 1,
|
| 322 |
+
'HAVE_MKFIFOAT': 1,
|
| 323 |
+
'HAVE_MKNOD': 1,
|
| 324 |
+
'HAVE_MKNODAT': 1,
|
| 325 |
+
'HAVE_MKTIME': 1,
|
| 326 |
+
'HAVE_MMAP': 1,
|
| 327 |
+
'HAVE_MREMAP': 1,
|
| 328 |
+
'HAVE_NCURSES_H': 1,
|
| 329 |
+
'HAVE_NDIR_H': 0,
|
| 330 |
+
'HAVE_NETPACKET_PACKET_H': 1,
|
| 331 |
+
'HAVE_NET_IF_H': 1,
|
| 332 |
+
'HAVE_NICE': 1,
|
| 333 |
+
'HAVE_OPENAT': 1,
|
| 334 |
+
'HAVE_OPENPTY': 1,
|
| 335 |
+
'HAVE_PATHCONF': 1,
|
| 336 |
+
'HAVE_PAUSE': 1,
|
| 337 |
+
'HAVE_PIPE2': 1,
|
| 338 |
+
'HAVE_PLOCK': 0,
|
| 339 |
+
'HAVE_POLL': 1,
|
| 340 |
+
'HAVE_POLL_H': 1,
|
| 341 |
+
'HAVE_POSIX_FADVISE': 1,
|
| 342 |
+
'HAVE_POSIX_FALLOCATE': 1,
|
| 343 |
+
'HAVE_POSIX_SPAWN': 1,
|
| 344 |
+
'HAVE_PREAD': 1,
|
| 345 |
+
'HAVE_PREADV': 1,
|
| 346 |
+
'HAVE_PREADV2': 0,
|
| 347 |
+
'HAVE_PRLIMIT': 1,
|
| 348 |
+
'HAVE_PROCESS_H': 0,
|
| 349 |
+
'HAVE_PROTOTYPES': 1,
|
| 350 |
+
'HAVE_PTHREAD_DESTRUCTOR': 0,
|
| 351 |
+
'HAVE_PTHREAD_ATFORK': 1,
|
| 352 |
+
'HAVE_PTHREAD_H': 1,
|
| 353 |
+
'HAVE_PTHREAD_INIT': 0,
|
| 354 |
+
'HAVE_PTHREAD_KILL': 1,
|
| 355 |
+
'HAVE_PTHREAD_SIGMASK': 1,
|
| 356 |
+
'HAVE_PTY_H': 1,
|
| 357 |
+
'HAVE_PUTENV': 1,
|
| 358 |
+
'HAVE_PWRITE': 1,
|
| 359 |
+
'HAVE_PWRITEV': 1,
|
| 360 |
+
'HAVE_PWRITEV2': 0,
|
| 361 |
+
'HAVE_READLINK': 1,
|
| 362 |
+
'HAVE_READLINKAT': 1,
|
| 363 |
+
'HAVE_READV': 1,
|
| 364 |
+
'HAVE_REALPATH': 1,
|
| 365 |
+
'HAVE_RENAMEAT': 1,
|
| 366 |
+
'HAVE_RL_APPEND_HISTORY': 1,
|
| 367 |
+
'HAVE_RL_CATCH_SIGNAL': 1,
|
| 368 |
+
'HAVE_RL_COMPLETION_APPEND_CHARACTER': 1,
|
| 369 |
+
'HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK': 1,
|
| 370 |
+
'HAVE_RL_COMPLETION_MATCHES': 1,
|
| 371 |
+
'HAVE_RL_COMPLETION_SUPPRESS_APPEND': 1,
|
| 372 |
+
'HAVE_RL_PRE_INPUT_HOOK': 1,
|
| 373 |
+
'HAVE_RL_RESIZE_TERMINAL': 1,
|
| 374 |
+
'HAVE_ROUND': 1,
|
| 375 |
+
'HAVE_SCHED_GET_PRIORITY_MAX': 1,
|
| 376 |
+
'HAVE_SCHED_H': 1,
|
| 377 |
+
'HAVE_SCHED_RR_GET_INTERVAL': 1,
|
| 378 |
+
'HAVE_SCHED_SETAFFINITY': 1,
|
| 379 |
+
'HAVE_SCHED_SETPARAM': 1,
|
| 380 |
+
'HAVE_SCHED_SETSCHEDULER': 1,
|
| 381 |
+
'HAVE_SEM_GETVALUE': 1,
|
| 382 |
+
'HAVE_SEM_OPEN': 1,
|
| 383 |
+
'HAVE_SEM_TIMEDWAIT': 1,
|
| 384 |
+
'HAVE_SEM_UNLINK': 1,
|
| 385 |
+
'HAVE_SENDFILE': 1,
|
| 386 |
+
'HAVE_SETEGID': 1,
|
| 387 |
+
'HAVE_SETEUID': 1,
|
| 388 |
+
'HAVE_SETGID': 1,
|
| 389 |
+
'HAVE_SETGROUPS': 1,
|
| 390 |
+
'HAVE_SETHOSTNAME': 1,
|
| 391 |
+
'HAVE_SETITIMER': 1,
|
| 392 |
+
'HAVE_SETLOCALE': 1,
|
| 393 |
+
'HAVE_SETPGID': 1,
|
| 394 |
+
'HAVE_SETPGRP': 1,
|
| 395 |
+
'HAVE_SETPRIORITY': 1,
|
| 396 |
+
'HAVE_SETREGID': 1,
|
| 397 |
+
'HAVE_SETRESGID': 1,
|
| 398 |
+
'HAVE_SETRESUID': 1,
|
| 399 |
+
'HAVE_SETREUID': 1,
|
| 400 |
+
'HAVE_SETSID': 1,
|
| 401 |
+
'HAVE_SETUID': 1,
|
| 402 |
+
'HAVE_SETVBUF': 1,
|
| 403 |
+
'HAVE_SHADOW_H': 1,
|
| 404 |
+
'HAVE_SIGACTION': 1,
|
| 405 |
+
'HAVE_SIGALTSTACK': 1,
|
| 406 |
+
'HAVE_SIGINFO_T_SI_BAND': 1,
|
| 407 |
+
'HAVE_SIGINTERRUPT': 1,
|
| 408 |
+
'HAVE_SIGNAL_H': 1,
|
| 409 |
+
'HAVE_SIGPENDING': 1,
|
| 410 |
+
'HAVE_SIGRELSE': 1,
|
| 411 |
+
'HAVE_SIGTIMEDWAIT': 1,
|
| 412 |
+
'HAVE_SIGWAIT': 1,
|
| 413 |
+
'HAVE_SIGWAITINFO': 1,
|
| 414 |
+
'HAVE_SNPRINTF': 1,
|
| 415 |
+
'HAVE_SOCKADDR_ALG': 1,
|
| 416 |
+
'HAVE_SOCKADDR_SA_LEN': 0,
|
| 417 |
+
'HAVE_SOCKADDR_STORAGE': 1,
|
| 418 |
+
'HAVE_SOCKETPAIR': 1,
|
| 419 |
+
'HAVE_SPAWN_H': 1,
|
| 420 |
+
'HAVE_SSIZE_T': 1,
|
| 421 |
+
'HAVE_STATVFS': 1,
|
| 422 |
+
'HAVE_STAT_TV_NSEC': 1,
|
| 423 |
+
'HAVE_STAT_TV_NSEC2': 0,
|
| 424 |
+
'HAVE_STDARG_PROTOTYPES': 1,
|
| 425 |
+
'HAVE_STDINT_H': 1,
|
| 426 |
+
'HAVE_STDLIB_H': 1,
|
| 427 |
+
'HAVE_STD_ATOMIC': 1,
|
| 428 |
+
'HAVE_STRDUP': 1,
|
| 429 |
+
'HAVE_STRFTIME': 1,
|
| 430 |
+
'HAVE_STRINGS_H': 1,
|
| 431 |
+
'HAVE_STRING_H': 1,
|
| 432 |
+
'HAVE_STRLCPY': 0,
|
| 433 |
+
'HAVE_STROPTS_H': 0,
|
| 434 |
+
'HAVE_STRUCT_PASSWD_PW_GECOS': 1,
|
| 435 |
+
'HAVE_STRUCT_PASSWD_PW_PASSWD': 1,
|
| 436 |
+
'HAVE_STRUCT_STAT_ST_BIRTHTIME': 0,
|
| 437 |
+
'HAVE_STRUCT_STAT_ST_BLKSIZE': 1,
|
| 438 |
+
'HAVE_STRUCT_STAT_ST_BLOCKS': 1,
|
| 439 |
+
'HAVE_STRUCT_STAT_ST_FLAGS': 0,
|
| 440 |
+
'HAVE_STRUCT_STAT_ST_GEN': 0,
|
| 441 |
+
'HAVE_STRUCT_STAT_ST_RDEV': 1,
|
| 442 |
+
'HAVE_STRUCT_TM_TM_ZONE': 1,
|
| 443 |
+
'HAVE_SYMLINK': 1,
|
| 444 |
+
'HAVE_SYMLINKAT': 1,
|
| 445 |
+
'HAVE_SYNC': 1,
|
| 446 |
+
'HAVE_SYSCONF': 1,
|
| 447 |
+
'HAVE_SYSEXITS_H': 1,
|
| 448 |
+
'HAVE_SYS_AUDIOIO_H': 0,
|
| 449 |
+
'HAVE_SYS_BSDTTY_H': 0,
|
| 450 |
+
'HAVE_SYS_DEVPOLL_H': 0,
|
| 451 |
+
'HAVE_SYS_DIR_H': 0,
|
| 452 |
+
'HAVE_SYS_ENDIAN_H': 0,
|
| 453 |
+
'HAVE_SYS_EPOLL_H': 1,
|
| 454 |
+
'HAVE_SYS_EVENT_H': 0,
|
| 455 |
+
'HAVE_SYS_FILE_H': 1,
|
| 456 |
+
'HAVE_SYS_IOCTL_H': 1,
|
| 457 |
+
'HAVE_SYS_KERN_CONTROL_H': 0,
|
| 458 |
+
'HAVE_SYS_LOADAVG_H': 0,
|
| 459 |
+
'HAVE_SYS_LOCK_H': 0,
|
| 460 |
+
'HAVE_SYS_MKDEV_H': 0,
|
| 461 |
+
'HAVE_SYS_MODEM_H': 0,
|
| 462 |
+
'HAVE_SYS_NDIR_H': 0,
|
| 463 |
+
'HAVE_SYS_PARAM_H': 1,
|
| 464 |
+
'HAVE_SYS_POLL_H': 1,
|
| 465 |
+
'HAVE_SYS_RANDOM_H': 0,
|
| 466 |
+
'HAVE_SYS_RESOURCE_H': 1,
|
| 467 |
+
'HAVE_SYS_SELECT_H': 1,
|
| 468 |
+
'HAVE_SYS_SENDFILE_H': 1,
|
| 469 |
+
'HAVE_SYS_SOCKET_H': 1,
|
| 470 |
+
'HAVE_SYS_STATVFS_H': 1,
|
| 471 |
+
'HAVE_SYS_STAT_H': 1,
|
| 472 |
+
'HAVE_SYS_SYSCALL_H': 1,
|
| 473 |
+
'HAVE_SYS_SYSMACROS_H': 1,
|
| 474 |
+
'HAVE_SYS_SYS_DOMAIN_H': 0,
|
| 475 |
+
'HAVE_SYS_TERMIO_H': 0,
|
| 476 |
+
'HAVE_SYS_TIMES_H': 1,
|
| 477 |
+
'HAVE_SYS_TIME_H': 1,
|
| 478 |
+
'HAVE_SYS_TYPES_H': 1,
|
| 479 |
+
'HAVE_SYS_UIO_H': 1,
|
| 480 |
+
'HAVE_SYS_UN_H': 1,
|
| 481 |
+
'HAVE_SYS_UTSNAME_H': 1,
|
| 482 |
+
'HAVE_SYS_WAIT_H': 1,
|
| 483 |
+
'HAVE_SYS_XATTR_H': 1,
|
| 484 |
+
'HAVE_TCGETPGRP': 1,
|
| 485 |
+
'HAVE_TCSETPGRP': 1,
|
| 486 |
+
'HAVE_TEMPNAM': 1,
|
| 487 |
+
'HAVE_TERMIOS_H': 1,
|
| 488 |
+
'HAVE_TERM_H': 1,
|
| 489 |
+
'HAVE_TGAMMA': 1,
|
| 490 |
+
'HAVE_TIMEGM': 1,
|
| 491 |
+
'HAVE_TIMES': 1,
|
| 492 |
+
'HAVE_TMPFILE': 1,
|
| 493 |
+
'HAVE_TMPNAM': 1,
|
| 494 |
+
'HAVE_TMPNAM_R': 1,
|
| 495 |
+
'HAVE_TM_ZONE': 1,
|
| 496 |
+
'HAVE_TRUNCATE': 1,
|
| 497 |
+
'HAVE_TZNAME': 0,
|
| 498 |
+
'HAVE_UCS4_TCL': 0,
|
| 499 |
+
'HAVE_UNAME': 1,
|
| 500 |
+
'HAVE_UNISTD_H': 1,
|
| 501 |
+
'HAVE_UNLINKAT': 1,
|
| 502 |
+
'HAVE_UNSETENV': 1,
|
| 503 |
+
'HAVE_USABLE_WCHAR_T': 0,
|
| 504 |
+
'HAVE_UTIL_H': 0,
|
| 505 |
+
'HAVE_UTIMENSAT': 1,
|
| 506 |
+
'HAVE_UTIMES': 1,
|
| 507 |
+
'HAVE_UTIME_H': 1,
|
| 508 |
+
'HAVE_UUID_CREATE': 0,
|
| 509 |
+
'HAVE_UUID_ENC_BE': 0,
|
| 510 |
+
'HAVE_UUID_GENERATE_TIME_SAFE': 0,
|
| 511 |
+
'HAVE_UUID_H': 0,
|
| 512 |
+
'HAVE_UUID_UUID_H': 0,
|
| 513 |
+
'HAVE_WAIT3': 1,
|
| 514 |
+
'HAVE_WAIT4': 1,
|
| 515 |
+
'HAVE_WAITID': 1,
|
| 516 |
+
'HAVE_WAITPID': 1,
|
| 517 |
+
'HAVE_WCHAR_H': 1,
|
| 518 |
+
'HAVE_WCSCOLL': 1,
|
| 519 |
+
'HAVE_WCSFTIME': 1,
|
| 520 |
+
'HAVE_WCSXFRM': 1,
|
| 521 |
+
'HAVE_WMEMCMP': 1,
|
| 522 |
+
'HAVE_WORKING_TZSET': 0,
|
| 523 |
+
'HAVE_WRITEV': 1,
|
| 524 |
+
'HAVE_X509_VERIFY_PARAM_SET1_HOST': 1,
|
| 525 |
+
'HAVE_ZLIB_COPY': 1,
|
| 526 |
+
'HAVE__GETPTY': 0,
|
| 527 |
+
'HOST_GNU_TYPE': 'aarch64-conda-linux-gnu',
|
| 528 |
+
'INCLDIRSTOMAKE': '/workspace/anaconda3/include '
|
| 529 |
+
'/workspace/anaconda3/include '
|
| 530 |
+
'/workspace/anaconda3/include/python3.8 '
|
| 531 |
+
'/workspace/anaconda3/include/python3.8',
|
| 532 |
+
'INCLUDEDIR': '/workspace/anaconda3/include',
|
| 533 |
+
'INCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 534 |
+
'INSTALL': '/usr/bin/install -c',
|
| 535 |
+
'INSTALL_DATA': '/usr/bin/install -c -m 644',
|
| 536 |
+
'INSTALL_PROGRAM': '/usr/bin/install -c',
|
| 537 |
+
'INSTALL_SCRIPT': '/usr/bin/install -c',
|
| 538 |
+
'INSTALL_SHARED': '/usr/bin/install -c -m 555',
|
| 539 |
+
'INSTSONAME': 'libpython3.8.a',
|
| 540 |
+
'IO_H': 'Modules/_io/_iomodule.h',
|
| 541 |
+
'IO_OBJS': '\\',
|
| 542 |
+
'LDCXXSHARED': 'aarch64-conda-linux-gnu-c++ -pthread -shared',
|
| 543 |
+
'LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 544 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 545 |
+
'-L/workspace/anaconda3/lib '
|
| 546 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 547 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 548 |
+
'-L/workspace/anaconda3/lib '
|
| 549 |
+
' ',
|
| 550 |
+
'LDLAST': '',
|
| 551 |
+
'LDLIBRARY': 'libpython3.8.a',
|
| 552 |
+
'LDLIBRARYDIR': '',
|
| 553 |
+
'LDSHARED': 'aarch64-conda-linux-gnu-gcc -pthread -shared -Wl,-O2 '
|
| 554 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 555 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 556 |
+
'-L/workspace/anaconda3/lib '
|
| 557 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 558 |
+
'-Wl,-z,now '
|
| 559 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 560 |
+
'-L/workspace/anaconda3/lib '
|
| 561 |
+
' ',
|
| 562 |
+
'LDVERSION': '3.8',
|
| 563 |
+
'LIBC': '',
|
| 564 |
+
'LIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 565 |
+
'LIBDIR': '/workspace/anaconda3/lib',
|
| 566 |
+
'LIBFFI_INCLUDEDIR': '/workspace/anaconda3/include',
|
| 567 |
+
'LIBM': '-lm',
|
| 568 |
+
'LIBOBJDIR': 'Python/',
|
| 569 |
+
'LIBOBJS': '',
|
| 570 |
+
'LIBPC': '/workspace/anaconda3/lib/pkgconfig',
|
| 571 |
+
'LIBPL':
|
| 572 |
+
'/workspace/anaconda3/lib/python3.8/config-3.8-aarch64-linux-gnu',
|
| 573 |
+
'LIBRARY': 'libpython3.8.a',
|
| 574 |
+
'LIBRARY_OBJS': '\\',
|
| 575 |
+
'LIBRARY_OBJS_OMIT_FROZEN': '\\',
|
| 576 |
+
'LIBS': '-lpthread -ldl -lutil',
|
| 577 |
+
'LIBSUBDIRS': 'tkinter tkinter/test tkinter/test/test_tkinter \\',
|
| 578 |
+
'LINKCC': 'aarch64-conda-linux-gnu-gcc -pthread',
|
| 579 |
+
'LINKFORSHARED': '-Xlinker -export-dynamic',
|
| 580 |
+
'LIPO_32BIT_FLAGS': '',
|
| 581 |
+
'LLVM_PROF_ERR': 'no',
|
| 582 |
+
'LLVM_PROF_FILE': '',
|
| 583 |
+
'LLVM_PROF_MERGER': 'true',
|
| 584 |
+
'LN': 'ln',
|
| 585 |
+
'LOCALMODLIBS': '',
|
| 586 |
+
'LOG1P_DROPS_ZERO_SIGN': 0,
|
| 587 |
+
'MACHDEP': 'linux',
|
| 588 |
+
'MACHDEPPATH': ':',
|
| 589 |
+
'MACHDEP_OBJS': '',
|
| 590 |
+
'MACHDESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 591 |
+
'MACOSX_DEPLOYMENT_TARGET': '',
|
| 592 |
+
'MAINCC': 'aarch64-conda-linux-gnu-gcc -pthread',
|
| 593 |
+
'MAJOR_IN_MKDEV': 0,
|
| 594 |
+
'MAJOR_IN_SYSMACROS': 0,
|
| 595 |
+
'MAKESETUP': '/opt/conda/conda-bld/python_1512347718438/work/Modules/makesetup',
|
| 596 |
+
'MANDIR': '/workspace/anaconda3/share/man',
|
| 597 |
+
'MKDIR_P': '/usr/bin/mkdir -p',
|
| 598 |
+
'MODBUILT_NAMES': 'posix errno pwd _sre _codecs _weakref _functools '
|
| 599 |
+
'_operator _collections _abc itertools atexit _signal '
|
| 600 |
+
'_stat time _thread _locale _io zipimport '
|
| 601 |
+
'faulthandler _tracemalloc _symtable xxsubtype',
|
| 602 |
+
'MODDISABLED_NAMES': '',
|
| 603 |
+
'MODLIBS': '',
|
| 604 |
+
'MODOBJS': 'Modules/posixmodule.o Modules/errnomodule.o '
|
| 605 |
+
'Modules/pwdmodule.o Modules/_sre.o Modules/_codecsmodule.o '
|
| 606 |
+
'Modules/_weakref.o Modules/_functoolsmodule.o '
|
| 607 |
+
'Modules/_operator.o Modules/_collectionsmodule.o '
|
| 608 |
+
'Modules/_abc.o Modules/itertoolsmodule.o '
|
| 609 |
+
'Modules/atexitmodule.o Modules/signalmodule.o Modules/_stat.o '
|
| 610 |
+
'Modules/timemodule.o Modules/_threadmodule.o '
|
| 611 |
+
'Modules/_localemodule.o Modules/_iomodule.o Modules/iobase.o '
|
| 612 |
+
'Modules/fileio.o Modules/bytesio.o Modules/bufferedio.o '
|
| 613 |
+
'Modules/textio.o Modules/stringio.o Modules/zipimport.o '
|
| 614 |
+
'Modules/faulthandler.o Modules/_tracemalloc.o '
|
| 615 |
+
'Modules/hashtable.o Modules/symtablemodule.o '
|
| 616 |
+
'Modules/xxsubtype.o',
|
| 617 |
+
'MODULE_OBJS': '\\',
|
| 618 |
+
'MULTIARCH': 'aarch64-linux-gnu',
|
| 619 |
+
'MULTIARCH_CPPFLAGS': '-DMULTIARCH=\\"aarch64-linux-gnu\\"',
|
| 620 |
+
'MVWDELCH_IS_EXPRESSION': 1,
|
| 621 |
+
'NO_AS_NEEDED': '-Wl,--no-as-needed',
|
| 622 |
+
'OPENSSL_INCLUDES': '-I/workspace/anaconda3/include',
|
| 623 |
+
'OPENSSL_LDFLAGS': '-L/workspace/anaconda3/lib',
|
| 624 |
+
'OPENSSL_LIBS': '-lssl -lcrypto',
|
| 625 |
+
'OBJECT_OBJS': '\\',
|
| 626 |
+
'OPT': '-DNDEBUG -fwrapv -O2 -Wall -Wstrict-prototypes',
|
| 627 |
+
'OTHER_LIBTOOL_OPT': '',
|
| 628 |
+
'PACKAGE_BUGREPORT': 0,
|
| 629 |
+
'PACKAGE_NAME': 0,
|
| 630 |
+
'PACKAGE_STRING': 0,
|
| 631 |
+
'PACKAGE_TARNAME': 0,
|
| 632 |
+
'PACKAGE_URL': 0,
|
| 633 |
+
'PACKAGE_VERSION': 0,
|
| 634 |
+
'PARSER_HEADERS': '\\',
|
| 635 |
+
'PARSER_OBJS': '\\ Parser/myreadline.o Parser/parsetok.o Parser/tokenizer.o',
|
| 636 |
+
'PGEN': 'Parser/pgen',
|
| 637 |
+
'PGENOBJS': '\\ \\',
|
| 638 |
+
'PGOBJS': '\\',
|
| 639 |
+
'PGO_PROF_GEN_FLAG': '-fprofile-generate',
|
| 640 |
+
'PGO_PROF_USE_FLAG': ' ',
|
| 641 |
+
'PLATDIR': '',
|
| 642 |
+
'POBJS': '\\',
|
| 643 |
+
'POSIX_SEMAPHORES_NOT_ENABLED': 0,
|
| 644 |
+
'PROFILE_TASK': '-m test.regrtest --pgo',
|
| 645 |
+
'PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT': 1,
|
| 646 |
+
'PTHREAD_SYSTEM_SCHED_SUPPORTED': 0,
|
| 647 |
+
'PURIFY': '',
|
| 648 |
+
'PY3LIBRARY': '',
|
| 649 |
+
'PYLONG_BITS_IN_DIGIT': 0,
|
| 650 |
+
'PYTHON': 'python',
|
| 651 |
+
'PYTHONFRAMEWORK': '',
|
| 652 |
+
'PYTHONFRAMEWORKDIR': 'no-framework',
|
| 653 |
+
'PYTHONFRAMEWORKINSTALLDIR': '',
|
| 654 |
+
'PYTHONFRAMEWORKPREFIX': '',
|
| 655 |
+
'PYTHONPATH': ':',
|
| 656 |
+
'PYTHON_FOR_BUILD': './python -E',
|
| 657 |
+
'PYTHON_FOR_REGEN': 'python3.8',
|
| 658 |
+
'PYTHON_HEADERS': '\\',
|
| 659 |
+
'PYTHON_OBJS': '\\',
|
| 660 |
+
'PY_BUILD_ENVIRON': '',
|
| 661 |
+
'PY_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall '
|
| 662 |
+
'-Wstrict-prototypes '
|
| 663 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong '
|
| 664 |
+
'-fno-plt -O2 '
|
| 665 |
+
'-pipe '
|
| 666 |
+
' '
|
| 667 |
+
'-ftree-vectorize -fPIC '
|
| 668 |
+
'-fstack-protector-strong -fno-plt -O2 '
|
| 669 |
+
'-pipe '
|
| 670 |
+
' ',
|
| 671 |
+
'PY_CFLAGS_NODIST': '-std=c99 -Wextra -Wno-unused-result '
|
| 672 |
+
'-Wno-unused-parameter -Wno-missing-field-initializers '
|
| 673 |
+
' '
|
| 674 |
+
'-ftree-vectorize -fPIC '
|
| 675 |
+
'-fstack-protector-strong -fno-plt -O2 '
|
| 676 |
+
'-pipe '
|
| 677 |
+
' '
|
| 678 |
+
' '
|
| 679 |
+
' ',
|
| 680 |
+
'PY_COERCE_C_LOCALE': 1,
|
| 681 |
+
'PY_CORE_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 '
|
| 682 |
+
'-Wall -Wstrict-prototypes '
|
| 683 |
+
'-ftree-vectorize -fPIC '
|
| 684 |
+
'-fstack-protector-strong -fno-plt -O2 '
|
| 685 |
+
'-pipe '
|
| 686 |
+
' '
|
| 687 |
+
'-ftree-vectorize -fPIC '
|
| 688 |
+
'-fstack-protector-strong -fno-plt -O2 '
|
| 689 |
+
'-pipe '
|
| 690 |
+
' -std=c99 -Wextra '
|
| 691 |
+
'-Wno-unused-result -Wno-unused-parameter '
|
| 692 |
+
'-Wno-missing-field-initializers '
|
| 693 |
+
'-ftree-vectorize -fPIC '
|
| 694 |
+
'-fstack-protector-strong -fno-plt -O2 '
|
| 695 |
+
'-pipe '
|
| 696 |
+
' '
|
| 697 |
+
' '
|
| 698 |
+
' -IObjects -IInclude '
|
| 699 |
+
'-IPython -I. '
|
| 700 |
+
'-I/opt/conda/conda-bld/python_1512347718438/work/Include '
|
| 701 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 702 |
+
'-I/workspace/anaconda3/include '
|
| 703 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 704 |
+
'-I/workspace/anaconda3/include '
|
| 705 |
+
'-DPy_BUILD_CORE',
|
| 706 |
+
'PY_CPPFLAGS': '-IObjects -IInclude -IPython -I. '
|
| 707 |
+
'-I/opt/conda/conda-bld/python_1512347718438/work/Include '
|
| 708 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 709 |
+
'-I/workspace/anaconda3/include '
|
| 710 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 711 |
+
'-I/workspace/anaconda3/include',
|
| 712 |
+
'PY_FORMAT_SIZE_T': '"z"',
|
| 713 |
+
'PY_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 714 |
+
'-Wl,-z,now '
|
| 715 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 716 |
+
'-L/workspace/anaconda3/lib '
|
| 717 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 718 |
+
'-Wl,-z,now '
|
| 719 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 720 |
+
'-L/workspace/anaconda3/lib '
|
| 721 |
+
' '
|
| 722 |
+
'',
|
| 723 |
+
'PY_SSL_DEFAULT_CIPHERS': 1,
|
| 724 |
+
'PY_SSL_DEFAULT_CIPHER_STRING': 0,
|
| 725 |
+
'PY_WARN_ON_C_LOCALE': 1,
|
| 726 |
+
'Py_DEBUG': 0,
|
| 727 |
+
'Py_ENABLE_SHARED': 0,
|
| 728 |
+
'Py_HASH_ALGORITHM': 0,
|
| 729 |
+
'QUICKTESTOPTS': '-x test_subprocess test_io test_lib2to3 \\',
|
| 730 |
+
'RANLIB': 'aarch64-conda-linux-gnu-ranlib',
|
| 731 |
+
'READELF': 'aarch64-conda-linux-gnu-readelf',
|
| 732 |
+
'RESSRCDIR': 'Mac/Resources/framework',
|
| 733 |
+
'RETSIGTYPE': 'void',
|
| 734 |
+
'RUNSHARED': '',
|
| 735 |
+
'SCRIPTDIR': '/workspace/anaconda3/lib',
|
| 736 |
+
'SETPGRP_HAVE_ARG': 0,
|
| 737 |
+
'SGI_ABI': '',
|
| 738 |
+
'SHELL': '/bin/sh',
|
| 739 |
+
'SHLIBS': '-lpthread -ldl -lutil',
|
| 740 |
+
'SHLIB_SUFFIX': '.so',
|
| 741 |
+
'SIGNED_RIGHT_SHIFT_ZERO_FILLS': 0,
|
| 742 |
+
'SITEPATH': '',
|
| 743 |
+
'SIZEOF_DOUBLE': 8,
|
| 744 |
+
'SIZEOF_FLOAT': 4,
|
| 745 |
+
'SIZEOF_FPOS_T': 16,
|
| 746 |
+
'SIZEOF_INT': 4,
|
| 747 |
+
'SIZEOF_LONG': 8,
|
| 748 |
+
'SIZEOF_LONG_DOUBLE': 16,
|
| 749 |
+
'SIZEOF_LONG_LONG': 8,
|
| 750 |
+
'SIZEOF_OFF_T': 8,
|
| 751 |
+
'SIZEOF_PID_T': 4,
|
| 752 |
+
'SIZEOF_PTHREAD_KEY_T': 4,
|
| 753 |
+
'SIZEOF_PTHREAD_T': 8,
|
| 754 |
+
'SIZEOF_SHORT': 2,
|
| 755 |
+
'SIZEOF_SIZE_T': 8,
|
| 756 |
+
'SIZEOF_TIME_T': 8,
|
| 757 |
+
'SIZEOF_UINTPTR_T': 8,
|
| 758 |
+
'SIZEOF_VOID_P': 8,
|
| 759 |
+
'SIZEOF_WCHAR_T': 4,
|
| 760 |
+
'SIZEOF__BOOL': 1,
|
| 761 |
+
'SOABI': 'cpython-38-aarch64-linux-gnu',
|
| 762 |
+
'SRCDIRS': 'Parser Grammar Objects Python Modules Mac Programs',
|
| 763 |
+
'SRC_GDB_HOOKS': '/opt/conda/conda-bld/python_1512347718438/work/Tools/gdb/libpython.py',
|
| 764 |
+
'STDC_HEADERS': 1,
|
| 765 |
+
'STRICT_SYSV_CURSES': "/* Don't use ncurses extensions */",
|
| 766 |
+
'STRIPFLAG': '-s',
|
| 767 |
+
'SUBDIRS': '',
|
| 768 |
+
'SUBDIRSTOO': 'Include Lib Misc',
|
| 769 |
+
'SYSLIBS': '-lm',
|
| 770 |
+
'SYS_SELECT_WITH_SYS_TIME': 1,
|
| 771 |
+
'TANH_PRESERVES_ZERO_SIGN': 0,
|
| 772 |
+
'TCLTK_INCLUDES': '-I/workspace/anaconda3/include',
|
| 773 |
+
'TCLTK_LIBS': '-L/workspace/anaconda3/lib '
|
| 774 |
+
'-ltcl8.6 -ltk8.6',
|
| 775 |
+
'TESTOPTS': '',
|
| 776 |
+
'TESTPATH': '',
|
| 777 |
+
'TESTPYTHON': './python',
|
| 778 |
+
'TESTPYTHONOPTS': '',
|
| 779 |
+
'TESTRUNNER': './python '
|
| 780 |
+
'/opt/conda/conda-bld/python_1512347718438/work/Tools/scripts/run_tests.py',
|
| 781 |
+
'TESTTIMEOUT': 1200,
|
| 782 |
+
'TIMEMODULE_LIB': 0,
|
| 783 |
+
'TIME_WITH_SYS_TIME': 1,
|
| 784 |
+
'TM_IN_SYS_TIME': 0,
|
| 785 |
+
'UNICODE_DEPS': '\\',
|
| 786 |
+
'UNIVERSALSDK': '',
|
| 787 |
+
'USE_COMPUTED_GOTOS': 1,
|
| 788 |
+
'VERSION': '3.8',
|
| 789 |
+
'VPATH': '/opt/conda/conda-bld/python_1512347718438/work',
|
| 790 |
+
'WINDOW_HAS_FLAGS': 1,
|
| 791 |
+
'WITH_DOC_STRINGS': 1,
|
| 792 |
+
'WITH_DTRACE': 0,
|
| 793 |
+
'WITH_DYLD': 0,
|
| 794 |
+
'WITH_LIBINTL': 0,
|
| 795 |
+
'WITH_NEXT_FRAMEWORK': 0,
|
| 796 |
+
'WITH_PYMALLOC': 1,
|
| 797 |
+
'WITH_VALGRIND': 0,
|
| 798 |
+
'X87_DOUBLE_ROUNDING': 0,
|
| 799 |
+
'XMLLIBSUBDIRS': 'xml xml/dom xml/etree xml/parsers xml/sax',
|
| 800 |
+
'abs_builddir': '/opt/conda/conda-bld/python_1512347718438/work/build-static',
|
| 801 |
+
'abs_srcdir': '/opt/conda/conda-bld/python_1512347718438/work',
|
| 802 |
+
'datarootdir': '/workspace/anaconda3/share',
|
| 803 |
+
'exec_prefix': '/workspace/anaconda3',
|
| 804 |
+
'prefix': '/workspace/anaconda3',
|
| 805 |
+
'srcdir': '/opt/conda/conda-bld/python_1512347718438/work'}
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata_i686_conda_cos6_linux_gnu.py
ADDED
|
@@ -0,0 +1,773 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# system configuration generated and used by the sysconfig module
|
| 2 |
+
build_time_vars = {'ABIFLAGS': '',
|
| 3 |
+
'AC_APPLE_UNIVERSAL_BUILD': 0,
|
| 4 |
+
'AIX_GENUINE_CPLUSPLUS': 0,
|
| 5 |
+
'ANDROID_API_LEVEL': 0,
|
| 6 |
+
'AR': 'i686-conda_cos6-linux-gnu-ar',
|
| 7 |
+
'ARFLAGS': 'rc',
|
| 8 |
+
'BASECFLAGS': '-Wno-unused-result -Wsign-compare',
|
| 9 |
+
'BASECPPFLAGS': '-IObjects -IInclude -IPython',
|
| 10 |
+
'BASEMODLIBS': '',
|
| 11 |
+
'BINDIR': '/workspace/anaconda3/bin',
|
| 12 |
+
'BINLIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 13 |
+
'BLDLIBRARY': 'libpython3.8.a',
|
| 14 |
+
'BLDSHARED': 'i686-conda_cos6-linux-gnu-gcc -pthread -shared -Wl,-O2 '
|
| 15 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 16 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 17 |
+
'-L/workspace/anaconda3/lib '
|
| 18 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 19 |
+
'-Wl,-z,now '
|
| 20 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 21 |
+
'-L/workspace/anaconda3/lib '
|
| 22 |
+
' '
|
| 23 |
+
'',
|
| 24 |
+
'BUILDEXE': '',
|
| 25 |
+
'BUILDPYTHON': 'python',
|
| 26 |
+
'BUILD_GNU_TYPE': 'i686-conda_cos6-linux-gnu',
|
| 27 |
+
'BYTESTR_DEPS': '\\',
|
| 28 |
+
'CC': 'i686-conda_cos6-linux-gnu-gcc -pthread',
|
| 29 |
+
'CCSHARED': '-fPIC',
|
| 30 |
+
'CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall '
|
| 31 |
+
'-Wstrict-prototypes -march=prescott -mtune=haswell '
|
| 32 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 -pipe '
|
| 33 |
+
' '
|
| 34 |
+
'-march=prescott -mtune=haswell -ftree-vectorize -fPIC '
|
| 35 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 36 |
+
' ',
|
| 37 |
+
'CFLAGSFORSHARED': '',
|
| 38 |
+
'CFLAGS_ALIASING': '',
|
| 39 |
+
'CONFIGFILES': 'configure configure.ac acconfig.h pyconfig.h.in '
|
| 40 |
+
'Makefile.pre.in',
|
| 41 |
+
'CONFIGURE_CFLAGS': '-march=prescott -mtune=haswell -ftree-vectorize -fPIC '
|
| 42 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 43 |
+
' '
|
| 44 |
+
' ',
|
| 45 |
+
'CONFIGURE_CFLAGS_NODIST': '-std=c99 -Wextra -Wno-unused-result '
|
| 46 |
+
'-Wno-unused-parameter '
|
| 47 |
+
'-Wno-missing-field-initializers',
|
| 48 |
+
'CONFIGURE_CPPFLAGS': '-D_FORTIFY_SOURCE=2 -O2 '
|
| 49 |
+
'-I/workspace/anaconda3/include',
|
| 50 |
+
'CONFIGURE_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 51 |
+
'-Wl,-z,now '
|
| 52 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 53 |
+
'-L/workspace/anaconda3/lib',
|
| 54 |
+
'CONFIG_ARGS': "'--prefix=/workspace/anaconda3' "
|
| 55 |
+
"'--build=i686-conda_cos6-linux-gnu' "
|
| 56 |
+
"'--host=i686-conda_cos6-linux-gnu' '--enable-ipv6' "
|
| 57 |
+
"'--with-ensurepip=no' '--with-computed-gotos' "
|
| 58 |
+
"'--with-system-ffi' '--enable-loadable-sqlite-extensions' "
|
| 59 |
+
"'--with-tcltk-includes=-I/workspace/anaconda3/include' "
|
| 60 |
+
"'--with-tcltk-libs=-L/workspace/anaconda3/lib "
|
| 61 |
+
"-ltcl8.6 -ltk8.6' '--enable-optimizations' '--with-lto' "
|
| 62 |
+
"'--disable-shared' 'build_alias=i686-conda_cos6-linux-gnu' "
|
| 63 |
+
"'host_alias=i686-conda_cos6-linux-gnu' "
|
| 64 |
+
"'CC=i686-conda_cos6-linux-gnu-gcc' 'CFLAGS=-march=prescott "
|
| 65 |
+
'-mtune=haswell -ftree-vectorize -fPIC '
|
| 66 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 67 |
+
' '
|
| 68 |
+
"' 'LDFLAGS=-Wl,-O2 -Wl,--sort-common -Wl,--as-needed "
|
| 69 |
+
'-Wl,-z,relro -Wl,-z,now '
|
| 70 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 71 |
+
"-L/workspace/anaconda3/lib' "
|
| 72 |
+
"'CPPFLAGS=-D_FORTIFY_SOURCE=2 -O2 "
|
| 73 |
+
"-I/workspace/anaconda3/include' "
|
| 74 |
+
"'CPP=/workspace/anaconda3/bin/i686-conda_cos6-linux-gnu-cpp' "
|
| 75 |
+
"'PKG_CONFIG_PATH=/workspace/anaconda3/lib/pkgconfig'",
|
| 76 |
+
'CONFINCLUDEDIR': '/workspace/anaconda3/include',
|
| 77 |
+
'CONFINCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 78 |
+
'COREPYTHONPATH': ':',
|
| 79 |
+
'COVERAGE_INFO': '/home/nwani/concourse_worker/containers/00003bfv1os/tmp/build/80754af9/python_1510184282133/work/build-static/coverage.info',
|
| 80 |
+
'COVERAGE_REPORT': '/home/nwani/concourse_worker/containers/00003bfv1os/tmp/build/80754af9/python_1510184282133/work/build-static/lcov-report',
|
| 81 |
+
'COVERAGE_REPORT_OPTIONS': '--no-branch-coverage --title "CPython lcov '
|
| 82 |
+
'report"',
|
| 83 |
+
'CPPFLAGS': '-IObjects -IInclude -IPython -I. '
|
| 84 |
+
'-I/home/nwani/concourse_worker/containers/00003bfv1os/tmp/build/80754af9/python_1510184282133/work/Include '
|
| 85 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 86 |
+
'-I/workspace/anaconda3/include '
|
| 87 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 88 |
+
'-I/workspace/anaconda3/include',
|
| 89 |
+
'CXX': 'i686-conda_cos6-linux-gnu-c++ -pthread',
|
| 90 |
+
'DESTDIRS': '/workspace/anaconda3 '
|
| 91 |
+
'/workspace/anaconda3/lib '
|
| 92 |
+
'/workspace/anaconda3/lib/python3.8 '
|
| 93 |
+
'/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 94 |
+
'DESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 95 |
+
'DESTPATH': '',
|
| 96 |
+
'DESTSHARED': '/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 97 |
+
'DFLAGS': '',
|
| 98 |
+
'DIRMODE': 755,
|
| 99 |
+
'DIST': 'README ChangeLog configure configure.ac acconfig.h pyconfig.h.in '
|
| 100 |
+
'Makefile.pre.in Include Lib Misc Ext-dummy',
|
| 101 |
+
'DISTDIRS': 'Include Lib Misc Ext-dummy',
|
| 102 |
+
'DISTFILES': 'README ChangeLog configure configure.ac acconfig.h '
|
| 103 |
+
'pyconfig.h.in Makefile.pre.in',
|
| 104 |
+
'DLINCLDIR': '.',
|
| 105 |
+
'DLLLIBRARY': '',
|
| 106 |
+
'DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754': 0,
|
| 107 |
+
'DOUBLE_IS_BIG_ENDIAN_IEEE754': 0,
|
| 108 |
+
'DOUBLE_IS_LITTLE_ENDIAN_IEEE754': 1,
|
| 109 |
+
'DTRACE': '',
|
| 110 |
+
'DTRACE_DEPS': '\\',
|
| 111 |
+
'DTRACE_HEADERS': '',
|
| 112 |
+
'DTRACE_OBJS': '',
|
| 113 |
+
'DYNLOADFILE': 'dynload_shlib.o',
|
| 114 |
+
'ENABLE_IPV6': 1,
|
| 115 |
+
'ENSUREPIP': 'no',
|
| 116 |
+
'EXE': '',
|
| 117 |
+
'EXEMODE': 755,
|
| 118 |
+
'EXTRAMACHDEPPATH': '',
|
| 119 |
+
'EXTRATESTOPTS': '',
|
| 120 |
+
'EXT_SUFFIX': '.cpython-38-i386-linux-gnu.so',
|
| 121 |
+
'FILEMODE': 644,
|
| 122 |
+
'FLOCK_NEEDS_LIBBSD': 0,
|
| 123 |
+
'GETPGRP_HAVE_ARG': 0,
|
| 124 |
+
'GETTIMEOFDAY_NO_TZ': 0,
|
| 125 |
+
'GITBRANCH': '',
|
| 126 |
+
'GITTAG': '',
|
| 127 |
+
'GITVERSION': '',
|
| 128 |
+
'GNULD': 'yes',
|
| 129 |
+
'HAVE_ACCEPT4': 1,
|
| 130 |
+
'HAVE_ACOSH': 1,
|
| 131 |
+
'HAVE_ADDRINFO': 1,
|
| 132 |
+
'HAVE_ALARM': 1,
|
| 133 |
+
'HAVE_ALIGNED_REQUIRED': 0,
|
| 134 |
+
'HAVE_ALLOCA_H': 1,
|
| 135 |
+
'HAVE_ALTZONE': 0,
|
| 136 |
+
'HAVE_ASINH': 1,
|
| 137 |
+
'HAVE_ASM_TYPES_H': 1,
|
| 138 |
+
'HAVE_ATANH': 1,
|
| 139 |
+
'HAVE_BIND_TEXTDOMAIN_CODESET': 1,
|
| 140 |
+
'HAVE_BLUETOOTH_BLUETOOTH_H': 0,
|
| 141 |
+
'HAVE_BLUETOOTH_H': 0,
|
| 142 |
+
'HAVE_BROKEN_MBSTOWCS': 0,
|
| 143 |
+
'HAVE_BROKEN_NICE': 0,
|
| 144 |
+
'HAVE_BROKEN_PIPE_BUF': 0,
|
| 145 |
+
'HAVE_BROKEN_POLL': 0,
|
| 146 |
+
'HAVE_BROKEN_POSIX_SEMAPHORES': 0,
|
| 147 |
+
'HAVE_BROKEN_PTHREAD_SIGMASK': 0,
|
| 148 |
+
'HAVE_BROKEN_SEM_GETVALUE': 0,
|
| 149 |
+
'HAVE_BROKEN_UNSETENV': 0,
|
| 150 |
+
'HAVE_BUILTIN_ATOMIC': 1,
|
| 151 |
+
'HAVE_CHFLAGS': 0,
|
| 152 |
+
'HAVE_CHOWN': 1,
|
| 153 |
+
'HAVE_CHROOT': 1,
|
| 154 |
+
'HAVE_CLOCK': 1,
|
| 155 |
+
'HAVE_CLOCK_GETRES': 1,
|
| 156 |
+
'HAVE_CLOCK_GETTIME': 1,
|
| 157 |
+
'HAVE_CLOCK_SETTIME': 1,
|
| 158 |
+
'HAVE_COMPUTED_GOTOS': 1,
|
| 159 |
+
'HAVE_CONFSTR': 1,
|
| 160 |
+
'HAVE_CONIO_H': 0,
|
| 161 |
+
'HAVE_COPYSIGN': 1,
|
| 162 |
+
'HAVE_CTERMID': 1,
|
| 163 |
+
'HAVE_CTERMID_R': 0,
|
| 164 |
+
'HAVE_CURSES_H': 1,
|
| 165 |
+
'HAVE_CURSES_IS_TERM_RESIZED': 1,
|
| 166 |
+
'HAVE_CURSES_RESIZETERM': 1,
|
| 167 |
+
'HAVE_CURSES_RESIZE_TERM': 1,
|
| 168 |
+
'HAVE_DECL_ISFINITE': 1,
|
| 169 |
+
'HAVE_DECL_ISINF': 1,
|
| 170 |
+
'HAVE_DECL_ISNAN': 1,
|
| 171 |
+
'HAVE_DECL_RTLD_DEEPBIND': 1,
|
| 172 |
+
'HAVE_DECL_RTLD_GLOBAL': 1,
|
| 173 |
+
'HAVE_DECL_RTLD_LAZY': 1,
|
| 174 |
+
'HAVE_DECL_RTLD_LOCAL': 1,
|
| 175 |
+
'HAVE_DECL_RTLD_NODELETE': 1,
|
| 176 |
+
'HAVE_DECL_RTLD_NOLOAD': 1,
|
| 177 |
+
'HAVE_DECL_RTLD_NOW': 1,
|
| 178 |
+
'HAVE_DECL_TZNAME': 0,
|
| 179 |
+
'HAVE_DEVICE_MACROS': 1,
|
| 180 |
+
'HAVE_DEV_PTC': 0,
|
| 181 |
+
'HAVE_DEV_PTMX': 1,
|
| 182 |
+
'HAVE_DIRECT_H': 0,
|
| 183 |
+
'HAVE_DIRENT_D_TYPE': 1,
|
| 184 |
+
'HAVE_DIRENT_H': 1,
|
| 185 |
+
'HAVE_DIRFD': 1,
|
| 186 |
+
'HAVE_DLFCN_H': 1,
|
| 187 |
+
'HAVE_DLOPEN': 1,
|
| 188 |
+
'HAVE_DUP2': 1,
|
| 189 |
+
'HAVE_DUP3': 1,
|
| 190 |
+
'HAVE_DYNAMIC_LOADING': 1,
|
| 191 |
+
'HAVE_ENDIAN_H': 1,
|
| 192 |
+
'HAVE_EPOLL': 1,
|
| 193 |
+
'HAVE_EPOLL_CREATE1': 1,
|
| 194 |
+
'HAVE_ERF': 1,
|
| 195 |
+
'HAVE_ERFC': 1,
|
| 196 |
+
'HAVE_ERRNO_H': 1,
|
| 197 |
+
'HAVE_EXECV': 1,
|
| 198 |
+
'HAVE_EXPM1': 1,
|
| 199 |
+
'HAVE_FACCESSAT': 1,
|
| 200 |
+
'HAVE_FCHDIR': 1,
|
| 201 |
+
'HAVE_FCHMOD': 1,
|
| 202 |
+
'HAVE_FCHMODAT': 1,
|
| 203 |
+
'HAVE_FCHOWN': 1,
|
| 204 |
+
'HAVE_FCHOWNAT': 1,
|
| 205 |
+
'HAVE_FCNTL_H': 1,
|
| 206 |
+
'HAVE_FDATASYNC': 1,
|
| 207 |
+
'HAVE_FDOPENDIR': 1,
|
| 208 |
+
'HAVE_FEXECVE': 1,
|
| 209 |
+
'HAVE_FINITE': 1,
|
| 210 |
+
'HAVE_FLOCK': 1,
|
| 211 |
+
'HAVE_FORK': 1,
|
| 212 |
+
'HAVE_FORKPTY': 1,
|
| 213 |
+
'HAVE_FPATHCONF': 1,
|
| 214 |
+
'HAVE_FSEEK64': 0,
|
| 215 |
+
'HAVE_FSEEKO': 1,
|
| 216 |
+
'HAVE_FSTATAT': 1,
|
| 217 |
+
'HAVE_FSTATVFS': 1,
|
| 218 |
+
'HAVE_FSYNC': 1,
|
| 219 |
+
'HAVE_FTELL64': 0,
|
| 220 |
+
'HAVE_FTELLO': 1,
|
| 221 |
+
'HAVE_FTIME': 1,
|
| 222 |
+
'HAVE_FTRUNCATE': 1,
|
| 223 |
+
'HAVE_FUTIMENS': 1,
|
| 224 |
+
'HAVE_FUTIMES': 1,
|
| 225 |
+
'HAVE_FUTIMESAT': 1,
|
| 226 |
+
'HAVE_GAI_STRERROR': 1,
|
| 227 |
+
'HAVE_GAMMA': 1,
|
| 228 |
+
'HAVE_GCC_ASM_FOR_MC68881': 0,
|
| 229 |
+
'HAVE_GCC_ASM_FOR_X64': 0,
|
| 230 |
+
'HAVE_GCC_ASM_FOR_X87': 1,
|
| 231 |
+
'HAVE_GCC_UINT128_T': 0,
|
| 232 |
+
'HAVE_GETADDRINFO': 1,
|
| 233 |
+
'HAVE_GETC_UNLOCKED': 1,
|
| 234 |
+
'HAVE_GETENTROPY': 0,
|
| 235 |
+
'HAVE_GETGROUPLIST': 1,
|
| 236 |
+
'HAVE_GETGROUPS': 1,
|
| 237 |
+
'HAVE_GETHOSTBYNAME': 0,
|
| 238 |
+
'HAVE_GETHOSTBYNAME_R': 1,
|
| 239 |
+
'HAVE_GETHOSTBYNAME_R_3_ARG': 0,
|
| 240 |
+
'HAVE_GETHOSTBYNAME_R_5_ARG': 0,
|
| 241 |
+
'HAVE_GETHOSTBYNAME_R_6_ARG': 1,
|
| 242 |
+
'HAVE_GETITIMER': 1,
|
| 243 |
+
'HAVE_GETLOADAVG': 1,
|
| 244 |
+
'HAVE_GETLOGIN': 1,
|
| 245 |
+
'HAVE_GETNAMEINFO': 1,
|
| 246 |
+
'HAVE_GETPAGESIZE': 1,
|
| 247 |
+
'HAVE_GETPEERNAME': 1,
|
| 248 |
+
'HAVE_GETPGID': 1,
|
| 249 |
+
'HAVE_GETPGRP': 1,
|
| 250 |
+
'HAVE_GETPID': 1,
|
| 251 |
+
'HAVE_GETPRIORITY': 1,
|
| 252 |
+
'HAVE_GETPWENT': 1,
|
| 253 |
+
'HAVE_GETRANDOM': 0,
|
| 254 |
+
'HAVE_GETRANDOM_SYSCALL': 0,
|
| 255 |
+
'HAVE_GETRESGID': 1,
|
| 256 |
+
'HAVE_GETRESUID': 1,
|
| 257 |
+
'HAVE_GETSID': 1,
|
| 258 |
+
'HAVE_GETSPENT': 1,
|
| 259 |
+
'HAVE_GETSPNAM': 1,
|
| 260 |
+
'HAVE_GETTIMEOFDAY': 1,
|
| 261 |
+
'HAVE_GETWD': 1,
|
| 262 |
+
'HAVE_GLIBC_MEMMOVE_BUG': 0,
|
| 263 |
+
'HAVE_GRP_H': 1,
|
| 264 |
+
'HAVE_HSTRERROR': 1,
|
| 265 |
+
'HAVE_HTOLE64': 1,
|
| 266 |
+
'HAVE_HYPOT': 1,
|
| 267 |
+
'HAVE_IEEEFP_H': 0,
|
| 268 |
+
'HAVE_IF_NAMEINDEX': 1,
|
| 269 |
+
'HAVE_INET_ATON': 1,
|
| 270 |
+
'HAVE_INET_PTON': 1,
|
| 271 |
+
'HAVE_INITGROUPS': 1,
|
| 272 |
+
'HAVE_INTTYPES_H': 1,
|
| 273 |
+
'HAVE_IO_H': 0,
|
| 274 |
+
'HAVE_IPA_PURE_CONST_BUG': 0,
|
| 275 |
+
'HAVE_KILL': 1,
|
| 276 |
+
'HAVE_KILLPG': 1,
|
| 277 |
+
'HAVE_KQUEUE': 0,
|
| 278 |
+
'HAVE_LANGINFO_H': 1,
|
| 279 |
+
'HAVE_LARGEFILE_SUPPORT': 1,
|
| 280 |
+
'HAVE_LCHFLAGS': 0,
|
| 281 |
+
'HAVE_LCHMOD': 0,
|
| 282 |
+
'HAVE_LCHOWN': 1,
|
| 283 |
+
'HAVE_LGAMMA': 1,
|
| 284 |
+
'HAVE_LIBDL': 1,
|
| 285 |
+
'HAVE_LIBDLD': 0,
|
| 286 |
+
'HAVE_LIBIEEE': 0,
|
| 287 |
+
'HAVE_LIBINTL_H': 1,
|
| 288 |
+
'HAVE_LIBREADLINE': 1,
|
| 289 |
+
'HAVE_LIBRESOLV': 0,
|
| 290 |
+
'HAVE_LIBSENDFILE': 0,
|
| 291 |
+
'HAVE_LIBUTIL_H': 0,
|
| 292 |
+
'HAVE_LINK': 1,
|
| 293 |
+
'HAVE_LINKAT': 1,
|
| 294 |
+
'HAVE_LINUX_CAN_BCM_H': 0,
|
| 295 |
+
'HAVE_LINUX_CAN_H': 1,
|
| 296 |
+
'HAVE_LINUX_CAN_RAW_FD_FRAMES': 0,
|
| 297 |
+
'HAVE_LINUX_CAN_RAW_H': 1,
|
| 298 |
+
'HAVE_LINUX_NETLINK_H': 1,
|
| 299 |
+
'HAVE_LINUX_RANDOM_H': 1,
|
| 300 |
+
'HAVE_LINUX_TIPC_H': 1,
|
| 301 |
+
'HAVE_LOCKF': 1,
|
| 302 |
+
'HAVE_LOG1P': 1,
|
| 303 |
+
'HAVE_LOG2': 1,
|
| 304 |
+
'HAVE_LONG_DOUBLE': 1,
|
| 305 |
+
'HAVE_LSTAT': 1,
|
| 306 |
+
'HAVE_LUTIMES': 1,
|
| 307 |
+
'HAVE_MAKEDEV': 1,
|
| 308 |
+
'HAVE_MBRTOWC': 1,
|
| 309 |
+
'HAVE_MEMMOVE': 1,
|
| 310 |
+
'HAVE_MEMORY_H': 1,
|
| 311 |
+
'HAVE_MEMRCHR': 1,
|
| 312 |
+
'HAVE_MKDIRAT': 1,
|
| 313 |
+
'HAVE_MKFIFO': 1,
|
| 314 |
+
'HAVE_MKFIFOAT': 1,
|
| 315 |
+
'HAVE_MKNOD': 1,
|
| 316 |
+
'HAVE_MKNODAT': 1,
|
| 317 |
+
'HAVE_MKTIME': 1,
|
| 318 |
+
'HAVE_MMAP': 1,
|
| 319 |
+
'HAVE_MREMAP': 1,
|
| 320 |
+
'HAVE_NCURSES_H': 1,
|
| 321 |
+
'HAVE_NDIR_H': 0,
|
| 322 |
+
'HAVE_NETPACKET_PACKET_H': 1,
|
| 323 |
+
'HAVE_NET_IF_H': 1,
|
| 324 |
+
'HAVE_NICE': 1,
|
| 325 |
+
'HAVE_OPENAT': 1,
|
| 326 |
+
'HAVE_OPENPTY': 1,
|
| 327 |
+
'HAVE_PATHCONF': 1,
|
| 328 |
+
'HAVE_PAUSE': 1,
|
| 329 |
+
'HAVE_PIPE2': 1,
|
| 330 |
+
'HAVE_PLOCK': 0,
|
| 331 |
+
'HAVE_POLL': 1,
|
| 332 |
+
'HAVE_POLL_H': 1,
|
| 333 |
+
'HAVE_POSIX_FADVISE': 1,
|
| 334 |
+
'HAVE_POSIX_FALLOCATE': 1,
|
| 335 |
+
'HAVE_PREAD': 1,
|
| 336 |
+
'HAVE_PRLIMIT': 0,
|
| 337 |
+
'HAVE_PROCESS_H': 0,
|
| 338 |
+
'HAVE_PROTOTYPES': 1,
|
| 339 |
+
'HAVE_PTHREAD_ATFORK': 1,
|
| 340 |
+
'HAVE_PTHREAD_DESTRUCTOR': 0,
|
| 341 |
+
'HAVE_PTHREAD_H': 1,
|
| 342 |
+
'HAVE_PTHREAD_INIT': 0,
|
| 343 |
+
'HAVE_PTHREAD_KILL': 1,
|
| 344 |
+
'HAVE_PTHREAD_SIGMASK': 1,
|
| 345 |
+
'HAVE_PTY_H': 1,
|
| 346 |
+
'HAVE_PUTENV': 1,
|
| 347 |
+
'HAVE_PWRITE': 1,
|
| 348 |
+
'HAVE_READLINK': 1,
|
| 349 |
+
'HAVE_READLINKAT': 1,
|
| 350 |
+
'HAVE_READV': 1,
|
| 351 |
+
'HAVE_REALPATH': 1,
|
| 352 |
+
'HAVE_RENAMEAT': 1,
|
| 353 |
+
'HAVE_RL_APPEND_HISTORY': 1,
|
| 354 |
+
'HAVE_RL_CALLBACK': 1,
|
| 355 |
+
'HAVE_RL_CATCH_SIGNAL': 1,
|
| 356 |
+
'HAVE_RL_COMPLETION_APPEND_CHARACTER': 1,
|
| 357 |
+
'HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK': 1,
|
| 358 |
+
'HAVE_RL_COMPLETION_MATCHES': 1,
|
| 359 |
+
'HAVE_RL_COMPLETION_SUPPRESS_APPEND': 1,
|
| 360 |
+
'HAVE_RL_PRE_INPUT_HOOK': 1,
|
| 361 |
+
'HAVE_RL_RESIZE_TERMINAL': 1,
|
| 362 |
+
'HAVE_ROUND': 1,
|
| 363 |
+
'HAVE_SCHED_GET_PRIORITY_MAX': 1,
|
| 364 |
+
'HAVE_SCHED_H': 1,
|
| 365 |
+
'HAVE_SCHED_RR_GET_INTERVAL': 1,
|
| 366 |
+
'HAVE_SCHED_SETAFFINITY': 1,
|
| 367 |
+
'HAVE_SCHED_SETPARAM': 1,
|
| 368 |
+
'HAVE_SCHED_SETSCHEDULER': 1,
|
| 369 |
+
'HAVE_SELECT': 1,
|
| 370 |
+
'HAVE_SEM_GETVALUE': 1,
|
| 371 |
+
'HAVE_SEM_OPEN': 1,
|
| 372 |
+
'HAVE_SEM_TIMEDWAIT': 1,
|
| 373 |
+
'HAVE_SEM_UNLINK': 1,
|
| 374 |
+
'HAVE_SENDFILE': 1,
|
| 375 |
+
'HAVE_SETEGID': 1,
|
| 376 |
+
'HAVE_SETEUID': 1,
|
| 377 |
+
'HAVE_SETGID': 1,
|
| 378 |
+
'HAVE_SETGROUPS': 1,
|
| 379 |
+
'HAVE_SETHOSTNAME': 1,
|
| 380 |
+
'HAVE_SETITIMER': 1,
|
| 381 |
+
'HAVE_SETLOCALE': 1,
|
| 382 |
+
'HAVE_SETPGID': 1,
|
| 383 |
+
'HAVE_SETPGRP': 1,
|
| 384 |
+
'HAVE_SETPRIORITY': 1,
|
| 385 |
+
'HAVE_SETREGID': 1,
|
| 386 |
+
'HAVE_SETRESGID': 1,
|
| 387 |
+
'HAVE_SETRESUID': 1,
|
| 388 |
+
'HAVE_SETREUID': 1,
|
| 389 |
+
'HAVE_SETSID': 1,
|
| 390 |
+
'HAVE_SETUID': 1,
|
| 391 |
+
'HAVE_SETVBUF': 1,
|
| 392 |
+
'HAVE_SHADOW_H': 1,
|
| 393 |
+
'HAVE_SIGACTION': 1,
|
| 394 |
+
'HAVE_SIGALTSTACK': 1,
|
| 395 |
+
'HAVE_SIGINTERRUPT': 1,
|
| 396 |
+
'HAVE_SIGNAL_H': 1,
|
| 397 |
+
'HAVE_SIGPENDING': 1,
|
| 398 |
+
'HAVE_SIGRELSE': 1,
|
| 399 |
+
'HAVE_SIGTIMEDWAIT': 1,
|
| 400 |
+
'HAVE_SIGWAIT': 1,
|
| 401 |
+
'HAVE_SIGWAITINFO': 1,
|
| 402 |
+
'HAVE_SNPRINTF': 1,
|
| 403 |
+
'HAVE_SOCKADDR_ALG': 0,
|
| 404 |
+
'HAVE_SOCKADDR_SA_LEN': 0,
|
| 405 |
+
'HAVE_SOCKADDR_STORAGE': 1,
|
| 406 |
+
'HAVE_SOCKETPAIR': 1,
|
| 407 |
+
'HAVE_SPAWN_H': 1,
|
| 408 |
+
'HAVE_SSIZE_T': 1,
|
| 409 |
+
'HAVE_STATVFS': 1,
|
| 410 |
+
'HAVE_STAT_TV_NSEC': 1,
|
| 411 |
+
'HAVE_STAT_TV_NSEC2': 0,
|
| 412 |
+
'HAVE_STDARG_PROTOTYPES': 1,
|
| 413 |
+
'HAVE_STDINT_H': 1,
|
| 414 |
+
'HAVE_STDLIB_H': 1,
|
| 415 |
+
'HAVE_STD_ATOMIC': 1,
|
| 416 |
+
'HAVE_STRDUP': 1,
|
| 417 |
+
'HAVE_STRFTIME': 1,
|
| 418 |
+
'HAVE_STRINGS_H': 1,
|
| 419 |
+
'HAVE_STRING_H': 1,
|
| 420 |
+
'HAVE_STRLCPY': 0,
|
| 421 |
+
'HAVE_STROPTS_H': 1,
|
| 422 |
+
'HAVE_STRUCT_PASSWD_PW_GECOS': 1,
|
| 423 |
+
'HAVE_STRUCT_PASSWD_PW_PASSWD': 1,
|
| 424 |
+
'HAVE_STRUCT_STAT_ST_BIRTHTIME': 0,
|
| 425 |
+
'HAVE_STRUCT_STAT_ST_BLKSIZE': 1,
|
| 426 |
+
'HAVE_STRUCT_STAT_ST_BLOCKS': 1,
|
| 427 |
+
'HAVE_STRUCT_STAT_ST_FLAGS': 0,
|
| 428 |
+
'HAVE_STRUCT_STAT_ST_GEN': 0,
|
| 429 |
+
'HAVE_STRUCT_STAT_ST_RDEV': 1,
|
| 430 |
+
'HAVE_STRUCT_TM_TM_ZONE': 1,
|
| 431 |
+
'HAVE_SYMLINK': 1,
|
| 432 |
+
'HAVE_SYMLINKAT': 1,
|
| 433 |
+
'HAVE_SYNC': 1,
|
| 434 |
+
'HAVE_SYSCONF': 1,
|
| 435 |
+
'HAVE_SYSEXITS_H': 1,
|
| 436 |
+
'HAVE_SYS_AUDIOIO_H': 0,
|
| 437 |
+
'HAVE_SYS_BSDTTY_H': 0,
|
| 438 |
+
'HAVE_SYS_DEVPOLL_H': 0,
|
| 439 |
+
'HAVE_SYS_DIR_H': 0,
|
| 440 |
+
'HAVE_SYS_ENDIAN_H': 0,
|
| 441 |
+
'HAVE_SYS_EPOLL_H': 1,
|
| 442 |
+
'HAVE_SYS_EVENT_H': 0,
|
| 443 |
+
'HAVE_SYS_FILE_H': 1,
|
| 444 |
+
'HAVE_SYS_IOCTL_H': 1,
|
| 445 |
+
'HAVE_SYS_KERN_CONTROL_H': 0,
|
| 446 |
+
'HAVE_SYS_LOADAVG_H': 0,
|
| 447 |
+
'HAVE_SYS_LOCK_H': 0,
|
| 448 |
+
'HAVE_SYS_MKDEV_H': 0,
|
| 449 |
+
'HAVE_SYS_MODEM_H': 0,
|
| 450 |
+
'HAVE_SYS_NDIR_H': 0,
|
| 451 |
+
'HAVE_SYS_PARAM_H': 1,
|
| 452 |
+
'HAVE_SYS_POLL_H': 1,
|
| 453 |
+
'HAVE_SYS_RANDOM_H': 0,
|
| 454 |
+
'HAVE_SYS_RESOURCE_H': 1,
|
| 455 |
+
'HAVE_SYS_SELECT_H': 1,
|
| 456 |
+
'HAVE_SYS_SENDFILE_H': 1,
|
| 457 |
+
'HAVE_SYS_SOCKET_H': 1,
|
| 458 |
+
'HAVE_SYS_STATVFS_H': 1,
|
| 459 |
+
'HAVE_SYS_STAT_H': 1,
|
| 460 |
+
'HAVE_SYS_SYSCALL_H': 1,
|
| 461 |
+
'HAVE_SYS_SYSMACROS_H': 1,
|
| 462 |
+
'HAVE_SYS_SYS_DOMAIN_H': 0,
|
| 463 |
+
'HAVE_SYS_TERMIO_H': 0,
|
| 464 |
+
'HAVE_SYS_TIMES_H': 1,
|
| 465 |
+
'HAVE_SYS_TIME_H': 1,
|
| 466 |
+
'HAVE_SYS_TYPES_H': 1,
|
| 467 |
+
'HAVE_SYS_UIO_H': 1,
|
| 468 |
+
'HAVE_SYS_UN_H': 1,
|
| 469 |
+
'HAVE_SYS_UTSNAME_H': 1,
|
| 470 |
+
'HAVE_SYS_WAIT_H': 1,
|
| 471 |
+
'HAVE_SYS_XATTR_H': 1,
|
| 472 |
+
'HAVE_TCGETPGRP': 1,
|
| 473 |
+
'HAVE_TCSETPGRP': 1,
|
| 474 |
+
'HAVE_TEMPNAM': 1,
|
| 475 |
+
'HAVE_TERMIOS_H': 1,
|
| 476 |
+
'HAVE_TERM_H': 1,
|
| 477 |
+
'HAVE_TGAMMA': 1,
|
| 478 |
+
'HAVE_TIMEGM': 1,
|
| 479 |
+
'HAVE_TIMES': 1,
|
| 480 |
+
'HAVE_TMPFILE': 1,
|
| 481 |
+
'HAVE_TMPNAM': 1,
|
| 482 |
+
'HAVE_TMPNAM_R': 1,
|
| 483 |
+
'HAVE_TM_ZONE': 1,
|
| 484 |
+
'HAVE_TRUNCATE': 1,
|
| 485 |
+
'HAVE_TZNAME': 0,
|
| 486 |
+
'HAVE_UCS4_TCL': 0,
|
| 487 |
+
'HAVE_UNAME': 1,
|
| 488 |
+
'HAVE_UNISTD_H': 1,
|
| 489 |
+
'HAVE_UNLINKAT': 1,
|
| 490 |
+
'HAVE_UNSETENV': 1,
|
| 491 |
+
'HAVE_USABLE_WCHAR_T': 0,
|
| 492 |
+
'HAVE_UTIL_H': 0,
|
| 493 |
+
'HAVE_UTIMENSAT': 1,
|
| 494 |
+
'HAVE_UTIMES': 1,
|
| 495 |
+
'HAVE_UTIME_H': 1,
|
| 496 |
+
'HAVE_WAIT3': 1,
|
| 497 |
+
'HAVE_WAIT4': 1,
|
| 498 |
+
'HAVE_WAITID': 1,
|
| 499 |
+
'HAVE_WAITPID': 1,
|
| 500 |
+
'HAVE_WCHAR_H': 1,
|
| 501 |
+
'HAVE_WCSCOLL': 1,
|
| 502 |
+
'HAVE_WCSFTIME': 1,
|
| 503 |
+
'HAVE_WCSXFRM': 1,
|
| 504 |
+
'HAVE_WMEMCMP': 1,
|
| 505 |
+
'HAVE_WORKING_TZSET': 1,
|
| 506 |
+
'HAVE_WRITEV': 1,
|
| 507 |
+
'HAVE_ZLIB_COPY': 1,
|
| 508 |
+
'HAVE__GETPTY': 0,
|
| 509 |
+
'HOST_GNU_TYPE': 'i686-conda_cos6-linux-gnu',
|
| 510 |
+
'INCLDIRSTOMAKE': '/workspace/anaconda3/include '
|
| 511 |
+
'/workspace/anaconda3/include '
|
| 512 |
+
'/workspace/anaconda3/include/python3.8 '
|
| 513 |
+
'/workspace/anaconda3/include/python3.8',
|
| 514 |
+
'INCLUDEDIR': '/workspace/anaconda3/include',
|
| 515 |
+
'INCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 516 |
+
'INSTALL': '/usr/bin/install -c',
|
| 517 |
+
'INSTALL_DATA': '/usr/bin/install -c -m 644',
|
| 518 |
+
'INSTALL_PROGRAM': '/usr/bin/install -c',
|
| 519 |
+
'INSTALL_SCRIPT': '/usr/bin/install -c',
|
| 520 |
+
'INSTALL_SHARED': '/usr/bin/install -c -m 555',
|
| 521 |
+
'INSTSONAME': 'libpython3.8.a',
|
| 522 |
+
'IO_H': 'Modules/_io/_iomodule.h',
|
| 523 |
+
'IO_OBJS': '\\',
|
| 524 |
+
'LDCXXSHARED': 'i686-conda_cos6-linux-gnu-c++ -pthread -shared',
|
| 525 |
+
'LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 526 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 527 |
+
'-L/workspace/anaconda3/lib '
|
| 528 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 529 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 530 |
+
'-L/workspace/anaconda3/lib '
|
| 531 |
+
' ',
|
| 532 |
+
'LDLAST': '',
|
| 533 |
+
'LDLIBRARY': 'libpython3.8.a',
|
| 534 |
+
'LDLIBRARYDIR': '',
|
| 535 |
+
'LDSHARED': 'i686-conda_cos6-linux-gnu-gcc -pthread -shared -Wl,-O2 '
|
| 536 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 537 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 538 |
+
'-L/workspace/anaconda3/lib '
|
| 539 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 540 |
+
'-Wl,-z,now '
|
| 541 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 542 |
+
'-L/workspace/anaconda3/lib '
|
| 543 |
+
' ',
|
| 544 |
+
'LDVERSION': '3.8',
|
| 545 |
+
'LIBC': '',
|
| 546 |
+
'LIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 547 |
+
'LIBDIR': '/workspace/anaconda3/lib',
|
| 548 |
+
'LIBFFI_INCLUDEDIR': '/workspace/anaconda3/include',
|
| 549 |
+
'LIBM': '-lm',
|
| 550 |
+
'LIBOBJDIR': 'Python/',
|
| 551 |
+
'LIBOBJS': '',
|
| 552 |
+
'LIBPC': '/workspace/anaconda3/lib/pkgconfig',
|
| 553 |
+
'LIBPL': '/workspace/anaconda3/lib/python3.8/config-3.8-i386-linux-gnu',
|
| 554 |
+
'LIBRARY': 'libpython3.8.a',
|
| 555 |
+
'LIBRARY_OBJS': '\\',
|
| 556 |
+
'LIBRARY_OBJS_OMIT_FROZEN': '\\',
|
| 557 |
+
'LIBS': '-lpthread -ldl -lutil -lrt',
|
| 558 |
+
'LIBSUBDIRS': 'tkinter tkinter/test tkinter/test/test_tkinter \\',
|
| 559 |
+
'LINKCC': 'i686-conda_cos6-linux-gnu-gcc -pthread',
|
| 560 |
+
'LINKFORSHARED': '-Xlinker -export-dynamic',
|
| 561 |
+
'LIPO_32BIT_FLAGS': '',
|
| 562 |
+
'LLVM_PROF_ERR': 'no',
|
| 563 |
+
'LLVM_PROF_FILE': '',
|
| 564 |
+
'LLVM_PROF_MERGER': 'true',
|
| 565 |
+
'LN': 'ln',
|
| 566 |
+
'LOCALMODLIBS': '',
|
| 567 |
+
'LOG1P_DROPS_ZERO_SIGN': 0,
|
| 568 |
+
'MACHDEP': 'linux',
|
| 569 |
+
'MACHDEPPATH': ':',
|
| 570 |
+
'MACHDEP_OBJS': '',
|
| 571 |
+
'MACHDESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 572 |
+
'MACOSX_DEPLOYMENT_TARGET': '',
|
| 573 |
+
'MAINCC': 'i686-conda_cos6-linux-gnu-gcc -pthread',
|
| 574 |
+
'MAJOR_IN_MKDEV': 0,
|
| 575 |
+
'MAJOR_IN_SYSMACROS': 0,
|
| 576 |
+
'MAKESETUP': '/home/nwani/concourse_worker/containers/00003bfv1os/tmp/build/80754af9/python_1510184282133/work/Modules/makesetup',
|
| 577 |
+
'MANDIR': '/workspace/anaconda3/share/man',
|
| 578 |
+
'MKDIR_P': '/bin/mkdir -p',
|
| 579 |
+
'MODLIBS': '',
|
| 580 |
+
'MODNAMES': '_thread posix errno pwd _sre _codecs _weakref _functools '
|
| 581 |
+
'_operator _collections itertools atexit _signal _stat time '
|
| 582 |
+
'_locale _io zipimport faulthandler _tracemalloc _symtable '
|
| 583 |
+
'xxsubtype',
|
| 584 |
+
'MODOBJS': 'Modules/_threadmodule.o Modules/posixmodule.o '
|
| 585 |
+
'Modules/errnomodule.o Modules/pwdmodule.o Modules/_sre.o '
|
| 586 |
+
'Modules/_codecsmodule.o Modules/_weakref.o '
|
| 587 |
+
'Modules/_functoolsmodule.o Modules/_operator.o '
|
| 588 |
+
'Modules/_collectionsmodule.o Modules/itertoolsmodule.o '
|
| 589 |
+
'Modules/atexitmodule.o Modules/signalmodule.o Modules/_stat.o '
|
| 590 |
+
'Modules/timemodule.o Modules/_localemodule.o '
|
| 591 |
+
'Modules/_iomodule.o Modules/iobase.o Modules/fileio.o '
|
| 592 |
+
'Modules/bytesio.o Modules/bufferedio.o Modules/textio.o '
|
| 593 |
+
'Modules/stringio.o Modules/zipimport.o Modules/faulthandler.o '
|
| 594 |
+
'Modules/_tracemalloc.o Modules/hashtable.o '
|
| 595 |
+
'Modules/symtablemodule.o Modules/xxsubtype.o',
|
| 596 |
+
'MODULE_OBJS': '\\',
|
| 597 |
+
'MULTIARCH': 'i386-linux-gnu',
|
| 598 |
+
'MULTIARCH_CPPFLAGS': '-DMULTIARCH=\\"i386-linux-gnu\\"',
|
| 599 |
+
'MVWDELCH_IS_EXPRESSION': 1,
|
| 600 |
+
'NO_AS_NEEDED': '-Wl,--no-as-needed',
|
| 601 |
+
'OBJECT_OBJS': '\\',
|
| 602 |
+
'OPT': '-DNDEBUG -fwrapv -O2 -Wall -Wstrict-prototypes',
|
| 603 |
+
'OTHER_LIBTOOL_OPT': '',
|
| 604 |
+
'PACKAGE_BUGREPORT': 0,
|
| 605 |
+
'PACKAGE_NAME': 0,
|
| 606 |
+
'PACKAGE_STRING': 0,
|
| 607 |
+
'PACKAGE_TARNAME': 0,
|
| 608 |
+
'PACKAGE_URL': 0,
|
| 609 |
+
'PACKAGE_VERSION': 0,
|
| 610 |
+
'PARSER_HEADERS': '\\',
|
| 611 |
+
'PARSER_OBJS': '\\ Parser/myreadline.o Parser/parsetok.o Parser/tokenizer.o',
|
| 612 |
+
'PGEN': 'Parser/pgen',
|
| 613 |
+
'PGENOBJS': '\\ \\',
|
| 614 |
+
'PGOBJS': '\\',
|
| 615 |
+
'PGO_PROF_GEN_FLAG': '-fprofile-generate',
|
| 616 |
+
'PGO_PROF_USE_FLAG': ' ',
|
| 617 |
+
'PLATDIR': '',
|
| 618 |
+
'POBJS': '\\',
|
| 619 |
+
'POSIX_SEMAPHORES_NOT_ENABLED': 0,
|
| 620 |
+
'PROFILE_TASK': '-m test.regrtest --pgo',
|
| 621 |
+
'PTHREAD_SYSTEM_SCHED_SUPPORTED': 1,
|
| 622 |
+
'PURIFY': '',
|
| 623 |
+
'PY3LIBRARY': '',
|
| 624 |
+
'PYLONG_BITS_IN_DIGIT': 0,
|
| 625 |
+
'PYTHON': 'python',
|
| 626 |
+
'PYTHONFRAMEWORK': '',
|
| 627 |
+
'PYTHONFRAMEWORKDIR': 'no-framework',
|
| 628 |
+
'PYTHONFRAMEWORKINSTALLDIR': '',
|
| 629 |
+
'PYTHONFRAMEWORKPREFIX': '',
|
| 630 |
+
'PYTHONPATH': ':',
|
| 631 |
+
'PYTHON_FOR_BUILD': './python -E',
|
| 632 |
+
'PYTHON_FOR_REGEN': 'python3.8',
|
| 633 |
+
'PYTHON_HEADERS': '\\',
|
| 634 |
+
'PYTHON_OBJS': '\\',
|
| 635 |
+
'PY_BUILD_ENVIRON': '',
|
| 636 |
+
'PY_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall '
|
| 637 |
+
'-Wstrict-prototypes -march=prescott -mtune=haswell '
|
| 638 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 '
|
| 639 |
+
'-pipe '
|
| 640 |
+
' -march=prescott -mtune=haswell '
|
| 641 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 '
|
| 642 |
+
'-pipe '
|
| 643 |
+
' ',
|
| 644 |
+
'PY_CFLAGS_NODIST': '-std=c99 -Wextra -Wno-unused-result '
|
| 645 |
+
'-Wno-unused-parameter -Wno-missing-field-initializers '
|
| 646 |
+
'-march=prescott -mtune=haswell -ftree-vectorize -fPIC '
|
| 647 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 648 |
+
' '
|
| 649 |
+
' '
|
| 650 |
+
' '
|
| 651 |
+
' ',
|
| 652 |
+
'PY_CORE_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 '
|
| 653 |
+
'-Wall -Wstrict-prototypes -march=prescott -mtune=haswell '
|
| 654 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt '
|
| 655 |
+
'-O2 -pipe '
|
| 656 |
+
' -march=prescott -mtune=haswell '
|
| 657 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt '
|
| 658 |
+
'-O2 -pipe '
|
| 659 |
+
' -std=c99 -Wextra '
|
| 660 |
+
'-Wno-unused-result -Wno-unused-parameter '
|
| 661 |
+
'-Wno-missing-field-initializers -march=prescott '
|
| 662 |
+
'-mtune=haswell -ftree-vectorize -fPIC '
|
| 663 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 664 |
+
' '
|
| 665 |
+
' '
|
| 666 |
+
' '
|
| 667 |
+
'-IObjects -IInclude -IPython -I. '
|
| 668 |
+
'-I/home/nwani/concourse_worker/containers/00003bfv1os/tmp/build/80754af9/python_1510184282133/work/Include '
|
| 669 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 670 |
+
'-I/workspace/anaconda3/include '
|
| 671 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 672 |
+
'-I/workspace/anaconda3/include '
|
| 673 |
+
'-DPy_BUILD_CORE',
|
| 674 |
+
'PY_CPPFLAGS': '-IObjects -IInclude -IPython -I. '
|
| 675 |
+
'-I/home/nwani/concourse_worker/containers/00003bfv1os/tmp/build/80754af9/python_1510184282133/work/Include '
|
| 676 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 677 |
+
'-I/workspace/anaconda3/include '
|
| 678 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 679 |
+
'-I/workspace/anaconda3/include',
|
| 680 |
+
'PY_FORMAT_SIZE_T': '"z"',
|
| 681 |
+
'PY_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 682 |
+
'-Wl,-z,now '
|
| 683 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 684 |
+
'-L/workspace/anaconda3/lib '
|
| 685 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 686 |
+
'-Wl,-z,now '
|
| 687 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 688 |
+
'-L/workspace/anaconda3/lib '
|
| 689 |
+
' '
|
| 690 |
+
'',
|
| 691 |
+
'Py_DEBUG': 0,
|
| 692 |
+
'Py_ENABLE_SHARED': 0,
|
| 693 |
+
'Py_HASH_ALGORITHM': 0,
|
| 694 |
+
'QUICKTESTOPTS': '-x test_subprocess test_io test_lib2to3 \\',
|
| 695 |
+
'RANLIB': 'i686-conda_cos6-linux-gnu-ranlib',
|
| 696 |
+
'READELF': 'i686-conda_cos6-linux-gnu-readelf',
|
| 697 |
+
'RESSRCDIR': 'Mac/Resources/framework',
|
| 698 |
+
'RETSIGTYPE': 'void',
|
| 699 |
+
'RUNSHARED': '',
|
| 700 |
+
'SCRIPTDIR': '/workspace/anaconda3/lib',
|
| 701 |
+
'SETPGRP_HAVE_ARG': 0,
|
| 702 |
+
'SGI_ABI': '',
|
| 703 |
+
'SHELL': '/bin/sh',
|
| 704 |
+
'SHLIBS': '-lpthread -ldl -lutil -lrt',
|
| 705 |
+
'SHLIB_SUFFIX': '.so',
|
| 706 |
+
'SIGNED_RIGHT_SHIFT_ZERO_FILLS': 0,
|
| 707 |
+
'SITEPATH': '',
|
| 708 |
+
'SIZEOF_DOUBLE': 8,
|
| 709 |
+
'SIZEOF_FLOAT': 4,
|
| 710 |
+
'SIZEOF_FPOS_T': 16,
|
| 711 |
+
'SIZEOF_INT': 4,
|
| 712 |
+
'SIZEOF_LONG': 4,
|
| 713 |
+
'SIZEOF_LONG_DOUBLE': 12,
|
| 714 |
+
'SIZEOF_LONG_LONG': 8,
|
| 715 |
+
'SIZEOF_OFF_T': 8,
|
| 716 |
+
'SIZEOF_PID_T': 4,
|
| 717 |
+
'SIZEOF_PTHREAD_T': 4,
|
| 718 |
+
'SIZEOF_SHORT': 2,
|
| 719 |
+
'SIZEOF_SIZE_T': 4,
|
| 720 |
+
'SIZEOF_TIME_T': 4,
|
| 721 |
+
'SIZEOF_UINTPTR_T': 4,
|
| 722 |
+
'SIZEOF_VOID_P': 4,
|
| 723 |
+
'SIZEOF_WCHAR_T': 4,
|
| 724 |
+
'SIZEOF__BOOL': 1,
|
| 725 |
+
'SOABI': 'cpython-38-i386-linux-gnu',
|
| 726 |
+
'SRCDIRS': 'Parser Grammar Objects Python Modules Mac Programs',
|
| 727 |
+
'SRC_GDB_HOOKS': '/home/nwani/concourse_worker/containers/00003bfv1os/tmp/build/80754af9/python_1510184282133/work/Tools/gdb/libpython.py',
|
| 728 |
+
'STDC_HEADERS': 1,
|
| 729 |
+
'STRICT_SYSV_CURSES': "/* Don't use ncurses extensions */",
|
| 730 |
+
'STRIPFLAG': '-s',
|
| 731 |
+
'SUBDIRS': '',
|
| 732 |
+
'SUBDIRSTOO': 'Include Lib Misc',
|
| 733 |
+
'SYSLIBS': '-lm',
|
| 734 |
+
'SYS_SELECT_WITH_SYS_TIME': 1,
|
| 735 |
+
'TANH_PRESERVES_ZERO_SIGN': 1,
|
| 736 |
+
'TCLTK_INCLUDES': '-I/workspace/anaconda3/include',
|
| 737 |
+
'TCLTK_LIBS': '-L/workspace/anaconda3/lib '
|
| 738 |
+
'-ltcl8.6 -ltk8.6',
|
| 739 |
+
'TESTOPTS': '',
|
| 740 |
+
'TESTPATH': '',
|
| 741 |
+
'TESTPYTHON': './python',
|
| 742 |
+
'TESTPYTHONOPTS': '',
|
| 743 |
+
'TESTRUNNER': './python '
|
| 744 |
+
'/home/nwani/concourse_worker/containers/00003bfv1os/tmp/build/80754af9/python_1510184282133/work/Tools/scripts/run_tests.py',
|
| 745 |
+
'TESTTIMEOUT': 1200,
|
| 746 |
+
'THREADOBJ': 'Python/thread.o',
|
| 747 |
+
'TIMEMODULE_LIB': 'rt',
|
| 748 |
+
'TIME_WITH_SYS_TIME': 1,
|
| 749 |
+
'TM_IN_SYS_TIME': 0,
|
| 750 |
+
'UNICODE_DEPS': '\\',
|
| 751 |
+
'UNIVERSALSDK': '',
|
| 752 |
+
'USE_COMPUTED_GOTOS': 1,
|
| 753 |
+
'USE_INLINE': 1,
|
| 754 |
+
'VERSION': '3.8',
|
| 755 |
+
'VPATH': '/home/nwani/concourse_worker/containers/00003bfv1os/tmp/build/80754af9/python_1510184282133/work',
|
| 756 |
+
'WANT_SIGFPE_HANDLER': 0,
|
| 757 |
+
'WINDOW_HAS_FLAGS': 1,
|
| 758 |
+
'WITH_DOC_STRINGS': 1,
|
| 759 |
+
'WITH_DTRACE': 0,
|
| 760 |
+
'WITH_DYLD': 0,
|
| 761 |
+
'WITH_LIBINTL': 0,
|
| 762 |
+
'WITH_NEXT_FRAMEWORK': 0,
|
| 763 |
+
'WITH_PYMALLOC': 1,
|
| 764 |
+
'WITH_THREAD': 1,
|
| 765 |
+
'WITH_VALGRIND': 0,
|
| 766 |
+
'X87_DOUBLE_ROUNDING': 1,
|
| 767 |
+
'XMLLIBSUBDIRS': 'xml xml/dom xml/etree xml/parsers xml/sax',
|
| 768 |
+
'abs_builddir': '/home/nwani/concourse_worker/containers/00003bfv1os/tmp/build/80754af9/python_1510184282133/work/build-static',
|
| 769 |
+
'abs_srcdir': '/home/nwani/concourse_worker/containers/00003bfv1os/tmp/build/80754af9/python_1510184282133/work',
|
| 770 |
+
'datarootdir': '/workspace/anaconda3/share',
|
| 771 |
+
'exec_prefix': '/workspace/anaconda3',
|
| 772 |
+
'prefix': '/workspace/anaconda3',
|
| 773 |
+
'srcdir': '/home/nwani/concourse_worker/containers/00003bfv1os/tmp/build/80754af9/python_1510184282133/work'}
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata_s390x_conda_linux_gnu.py
ADDED
|
@@ -0,0 +1,773 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# system configuration generated and used by the sysconfig module
|
| 2 |
+
build_time_vars = {'ABIFLAGS': '',
|
| 3 |
+
'AC_APPLE_UNIVERSAL_BUILD': 0,
|
| 4 |
+
'AIX_GENUINE_CPLUSPLUS': 0,
|
| 5 |
+
'ANDROID_API_LEVEL': 0,
|
| 6 |
+
'AR': 's390x-conda-linux-gnu-ar',
|
| 7 |
+
'ARFLAGS': 'rc',
|
| 8 |
+
'BASECFLAGS': '-Wno-unused-result -Wsign-compare',
|
| 9 |
+
'BASECPPFLAGS': '-IObjects -IInclude -IPython',
|
| 10 |
+
'BASEMODLIBS': '',
|
| 11 |
+
'BINDIR': '/workspace/anaconda3/bin',
|
| 12 |
+
'BINLIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 13 |
+
'BLDLIBRARY': 'libpython3.8.a',
|
| 14 |
+
'BLDSHARED': 's390x-conda-linux-gnu-gcc -pthread -shared -Wl,-O2 '
|
| 15 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 16 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 17 |
+
'-L/workspace/anaconda3/lib '
|
| 18 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 19 |
+
'-Wl,-z,now '
|
| 20 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 21 |
+
'-L/workspace/anaconda3/lib '
|
| 22 |
+
' '
|
| 23 |
+
'',
|
| 24 |
+
'BUILDEXE': '',
|
| 25 |
+
'BUILDPYTHON': 'python',
|
| 26 |
+
'BUILD_GNU_TYPE': 's390x-conda-linux-gnu',
|
| 27 |
+
'BYTESTR_DEPS': '\\',
|
| 28 |
+
'CC': 's390x-conda-linux-gnu-gcc -pthread',
|
| 29 |
+
'CCSHARED': '-fPIC',
|
| 30 |
+
'CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall '
|
| 31 |
+
'-Wstrict-prototypes -march=z14 -mtune=z14 -ftree-vectorize '
|
| 32 |
+
'-fPIC -fstack-protector-strong -fno-plt -O2 -pipe '
|
| 33 |
+
' '
|
| 34 |
+
'-march=z14 -mtune=z14 -ftree-vectorize -fPIC '
|
| 35 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 36 |
+
' ',
|
| 37 |
+
'CFLAGSFORSHARED': '',
|
| 38 |
+
'CFLAGS_ALIASING': '',
|
| 39 |
+
'CONFIGFILES': 'configure configure.ac acconfig.h pyconfig.h.in '
|
| 40 |
+
'Makefile.pre.in',
|
| 41 |
+
'CONFIGURE_CFLAGS': '-march=z14 -mtune=z14 -ftree-vectorize -fPIC '
|
| 42 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 43 |
+
' '
|
| 44 |
+
' ',
|
| 45 |
+
'CONFIGURE_CFLAGS_NODIST': '-std=c99 -Wextra -Wno-unused-result '
|
| 46 |
+
'-Wno-unused-parameter '
|
| 47 |
+
'-Wno-missing-field-initializers',
|
| 48 |
+
'CONFIGURE_CPPFLAGS': '-D_FORTIFY_SOURCE=2 -O2 '
|
| 49 |
+
'-I/workspace/anaconda3/include',
|
| 50 |
+
'CONFIGURE_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 51 |
+
'-Wl,-z,now '
|
| 52 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 53 |
+
'-L/workspace/anaconda3/lib',
|
| 54 |
+
'CONFIG_ARGS': "'--prefix=/workspace/anaconda3' "
|
| 55 |
+
"'--build=s390x-conda-linux-gnu' "
|
| 56 |
+
"'--host=s390x-conda-linux-gnu' '--enable-ipv6' "
|
| 57 |
+
"'--with-ensurepip=no' '--with-computed-gotos' "
|
| 58 |
+
"'--with-system-ffi' '--enable-loadable-sqlite-extensions' "
|
| 59 |
+
"'--with-tcltk-includes=-I/workspace/anaconda3/include' "
|
| 60 |
+
"'--with-tcltk-libs=-L/workspace/anaconda3/lib "
|
| 61 |
+
"-ltcl8.6 -ltk8.6' '--enable-optimizations' '--with-lto' "
|
| 62 |
+
"'--disable-shared' 'build_alias=s390x-conda-linux-gnu' "
|
| 63 |
+
"'host_alias=s390x-conda-linux-gnu' "
|
| 64 |
+
"'CC=s390x-conda-linux-gnu-gcc' 'CFLAGS=-march=z14 "
|
| 65 |
+
'-mtune=z14 -ftree-vectorize -fPIC '
|
| 66 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 67 |
+
' '
|
| 68 |
+
"' 'LDFLAGS=-Wl,-O2 -Wl,--sort-common -Wl,--as-needed "
|
| 69 |
+
'-Wl,-z,relro -Wl,-z,now '
|
| 70 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 71 |
+
"-L/workspace/anaconda3/lib' "
|
| 72 |
+
"'CPPFLAGS=-D_FORTIFY_SOURCE=2 -O2 "
|
| 73 |
+
"-I/workspace/anaconda3/include' "
|
| 74 |
+
"'CPP=/workspace/anaconda3/bin/s390x-conda-linux-gnu-cpp' "
|
| 75 |
+
"'PKG_CONFIG_PATH=/workspace/anaconda3/lib/pkgconfig'",
|
| 76 |
+
'CONFINCLUDEDIR': '/workspace/anaconda3/include',
|
| 77 |
+
'CONFINCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 78 |
+
'COREPYTHONPATH': ':',
|
| 79 |
+
'COVERAGE_INFO': '/tmp/build/80754af9/python_1510184704423/work/build-static/coverage.info',
|
| 80 |
+
'COVERAGE_REPORT': '/tmp/build/80754af9/python_1510184704423/work/build-static/lcov-report',
|
| 81 |
+
'COVERAGE_REPORT_OPTIONS': '--no-branch-coverage --title "CPython lcov '
|
| 82 |
+
'report"',
|
| 83 |
+
'CPPFLAGS': '-IObjects -IInclude -IPython -I. '
|
| 84 |
+
'-I/tmp/build/80754af9/python_1510184704423/work/Include '
|
| 85 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 86 |
+
'-I/workspace/anaconda3/include '
|
| 87 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 88 |
+
'-I/workspace/anaconda3/include',
|
| 89 |
+
'CXX': 's390x-conda-linux-gnu-c++ -pthread',
|
| 90 |
+
'DESTDIRS': '/workspace/anaconda3 '
|
| 91 |
+
'/workspace/anaconda3/lib '
|
| 92 |
+
'/workspace/anaconda3/lib/python3.8 '
|
| 93 |
+
'/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 94 |
+
'DESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 95 |
+
'DESTPATH': '',
|
| 96 |
+
'DESTSHARED': '/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 97 |
+
'DFLAGS': '',
|
| 98 |
+
'DIRMODE': 755,
|
| 99 |
+
'DIST': 'README ChangeLog configure configure.ac acconfig.h pyconfig.h.in '
|
| 100 |
+
'Makefile.pre.in Include Lib Misc Ext-dummy',
|
| 101 |
+
'DISTDIRS': 'Include Lib Misc Ext-dummy',
|
| 102 |
+
'DISTFILES': 'README ChangeLog configure configure.ac acconfig.h '
|
| 103 |
+
'pyconfig.h.in Makefile.pre.in',
|
| 104 |
+
'DLINCLDIR': '.',
|
| 105 |
+
'DLLLIBRARY': '',
|
| 106 |
+
'DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754': 0,
|
| 107 |
+
'DOUBLE_IS_BIG_ENDIAN_IEEE754': 0,
|
| 108 |
+
'DOUBLE_IS_LITTLE_ENDIAN_IEEE754': 1,
|
| 109 |
+
'DTRACE': '',
|
| 110 |
+
'DTRACE_DEPS': '\\',
|
| 111 |
+
'DTRACE_HEADERS': '',
|
| 112 |
+
'DTRACE_OBJS': '',
|
| 113 |
+
'DYNLOADFILE': 'dynload_shlib.o',
|
| 114 |
+
'ENABLE_IPV6': 1,
|
| 115 |
+
'ENSUREPIP': 'no',
|
| 116 |
+
'EXE': '',
|
| 117 |
+
'EXEMODE': 755,
|
| 118 |
+
'EXTRAMACHDEPPATH': '',
|
| 119 |
+
'EXTRATESTOPTS': '',
|
| 120 |
+
'EXT_SUFFIX': '.cpython-38-s390x-linux-gnu.so',
|
| 121 |
+
'FILEMODE': 644,
|
| 122 |
+
'FLOCK_NEEDS_LIBBSD': 0,
|
| 123 |
+
'GETPGRP_HAVE_ARG': 0,
|
| 124 |
+
'GETTIMEOFDAY_NO_TZ': 0,
|
| 125 |
+
'GITBRANCH': '',
|
| 126 |
+
'GITTAG': '',
|
| 127 |
+
'GITVERSION': '',
|
| 128 |
+
'GNULD': 'yes',
|
| 129 |
+
'HAVE_ACCEPT4': 1,
|
| 130 |
+
'HAVE_ACOSH': 1,
|
| 131 |
+
'HAVE_ADDRINFO': 1,
|
| 132 |
+
'HAVE_ALARM': 1,
|
| 133 |
+
'HAVE_ALIGNED_REQUIRED': 0,
|
| 134 |
+
'HAVE_ALLOCA_H': 1,
|
| 135 |
+
'HAVE_ALTZONE': 0,
|
| 136 |
+
'HAVE_ASINH': 1,
|
| 137 |
+
'HAVE_ASM_TYPES_H': 1,
|
| 138 |
+
'HAVE_ATANH': 1,
|
| 139 |
+
'HAVE_BIND_TEXTDOMAIN_CODESET': 1,
|
| 140 |
+
'HAVE_BLUETOOTH_BLUETOOTH_H': 0,
|
| 141 |
+
'HAVE_BLUETOOTH_H': 0,
|
| 142 |
+
'HAVE_BROKEN_MBSTOWCS': 0,
|
| 143 |
+
'HAVE_BROKEN_NICE': 0,
|
| 144 |
+
'HAVE_BROKEN_PIPE_BUF': 0,
|
| 145 |
+
'HAVE_BROKEN_POLL': 0,
|
| 146 |
+
'HAVE_BROKEN_POSIX_SEMAPHORES': 0,
|
| 147 |
+
'HAVE_BROKEN_PTHREAD_SIGMASK': 0,
|
| 148 |
+
'HAVE_BROKEN_SEM_GETVALUE': 0,
|
| 149 |
+
'HAVE_BROKEN_UNSETENV': 0,
|
| 150 |
+
'HAVE_BUILTIN_ATOMIC': 1,
|
| 151 |
+
'HAVE_CHFLAGS': 0,
|
| 152 |
+
'HAVE_CHOWN': 1,
|
| 153 |
+
'HAVE_CHROOT': 1,
|
| 154 |
+
'HAVE_CLOCK': 1,
|
| 155 |
+
'HAVE_CLOCK_GETRES': 1,
|
| 156 |
+
'HAVE_CLOCK_GETTIME': 1,
|
| 157 |
+
'HAVE_CLOCK_SETTIME': 1,
|
| 158 |
+
'HAVE_COMPUTED_GOTOS': 1,
|
| 159 |
+
'HAVE_CONFSTR': 1,
|
| 160 |
+
'HAVE_CONIO_H': 0,
|
| 161 |
+
'HAVE_COPYSIGN': 1,
|
| 162 |
+
'HAVE_CTERMID': 1,
|
| 163 |
+
'HAVE_CTERMID_R': 0,
|
| 164 |
+
'HAVE_CURSES_H': 1,
|
| 165 |
+
'HAVE_CURSES_IS_TERM_RESIZED': 1,
|
| 166 |
+
'HAVE_CURSES_RESIZETERM': 1,
|
| 167 |
+
'HAVE_CURSES_RESIZE_TERM': 1,
|
| 168 |
+
'HAVE_DECL_ISFINITE': 1,
|
| 169 |
+
'HAVE_DECL_ISINF': 1,
|
| 170 |
+
'HAVE_DECL_ISNAN': 1,
|
| 171 |
+
'HAVE_DECL_RTLD_DEEPBIND': 1,
|
| 172 |
+
'HAVE_DECL_RTLD_GLOBAL': 1,
|
| 173 |
+
'HAVE_DECL_RTLD_LAZY': 1,
|
| 174 |
+
'HAVE_DECL_RTLD_LOCAL': 1,
|
| 175 |
+
'HAVE_DECL_RTLD_NODELETE': 1,
|
| 176 |
+
'HAVE_DECL_RTLD_NOLOAD': 1,
|
| 177 |
+
'HAVE_DECL_RTLD_NOW': 1,
|
| 178 |
+
'HAVE_DECL_TZNAME': 0,
|
| 179 |
+
'HAVE_DEVICE_MACROS': 1,
|
| 180 |
+
'HAVE_DEV_PTC': 0,
|
| 181 |
+
'HAVE_DEV_PTMX': 1,
|
| 182 |
+
'HAVE_DIRECT_H': 0,
|
| 183 |
+
'HAVE_DIRENT_D_TYPE': 1,
|
| 184 |
+
'HAVE_DIRENT_H': 1,
|
| 185 |
+
'HAVE_DIRFD': 1,
|
| 186 |
+
'HAVE_DLFCN_H': 1,
|
| 187 |
+
'HAVE_DLOPEN': 1,
|
| 188 |
+
'HAVE_DUP2': 1,
|
| 189 |
+
'HAVE_DUP3': 1,
|
| 190 |
+
'HAVE_DYNAMIC_LOADING': 1,
|
| 191 |
+
'HAVE_ENDIAN_H': 1,
|
| 192 |
+
'HAVE_EPOLL': 1,
|
| 193 |
+
'HAVE_EPOLL_CREATE1': 1,
|
| 194 |
+
'HAVE_ERF': 1,
|
| 195 |
+
'HAVE_ERFC': 1,
|
| 196 |
+
'HAVE_ERRNO_H': 1,
|
| 197 |
+
'HAVE_EXECV': 1,
|
| 198 |
+
'HAVE_EXPM1': 1,
|
| 199 |
+
'HAVE_FACCESSAT': 1,
|
| 200 |
+
'HAVE_FCHDIR': 1,
|
| 201 |
+
'HAVE_FCHMOD': 1,
|
| 202 |
+
'HAVE_FCHMODAT': 1,
|
| 203 |
+
'HAVE_FCHOWN': 1,
|
| 204 |
+
'HAVE_FCHOWNAT': 1,
|
| 205 |
+
'HAVE_FCNTL_H': 1,
|
| 206 |
+
'HAVE_FDATASYNC': 1,
|
| 207 |
+
'HAVE_FDOPENDIR': 1,
|
| 208 |
+
'HAVE_FEXECVE': 1,
|
| 209 |
+
'HAVE_FINITE': 1,
|
| 210 |
+
'HAVE_FLOCK': 1,
|
| 211 |
+
'HAVE_FORK': 1,
|
| 212 |
+
'HAVE_FORKPTY': 1,
|
| 213 |
+
'HAVE_FPATHCONF': 1,
|
| 214 |
+
'HAVE_FSEEK64': 0,
|
| 215 |
+
'HAVE_FSEEKO': 1,
|
| 216 |
+
'HAVE_FSTATAT': 1,
|
| 217 |
+
'HAVE_FSTATVFS': 1,
|
| 218 |
+
'HAVE_FSYNC': 1,
|
| 219 |
+
'HAVE_FTELL64': 0,
|
| 220 |
+
'HAVE_FTELLO': 1,
|
| 221 |
+
'HAVE_FTIME': 1,
|
| 222 |
+
'HAVE_FTRUNCATE': 1,
|
| 223 |
+
'HAVE_FUTIMENS': 1,
|
| 224 |
+
'HAVE_FUTIMES': 1,
|
| 225 |
+
'HAVE_FUTIMESAT': 1,
|
| 226 |
+
'HAVE_GAI_STRERROR': 1,
|
| 227 |
+
'HAVE_GAMMA': 1,
|
| 228 |
+
'HAVE_GCC_ASM_FOR_MC68881': 0,
|
| 229 |
+
'HAVE_GCC_ASM_FOR_X64': 1,
|
| 230 |
+
'HAVE_GCC_ASM_FOR_X87': 1,
|
| 231 |
+
'HAVE_GCC_UINT128_T': 1,
|
| 232 |
+
'HAVE_GETADDRINFO': 1,
|
| 233 |
+
'HAVE_GETC_UNLOCKED': 1,
|
| 234 |
+
'HAVE_GETENTROPY': 0,
|
| 235 |
+
'HAVE_GETGROUPLIST': 1,
|
| 236 |
+
'HAVE_GETGROUPS': 1,
|
| 237 |
+
'HAVE_GETHOSTBYNAME': 0,
|
| 238 |
+
'HAVE_GETHOSTBYNAME_R': 1,
|
| 239 |
+
'HAVE_GETHOSTBYNAME_R_3_ARG': 0,
|
| 240 |
+
'HAVE_GETHOSTBYNAME_R_5_ARG': 0,
|
| 241 |
+
'HAVE_GETHOSTBYNAME_R_6_ARG': 1,
|
| 242 |
+
'HAVE_GETITIMER': 1,
|
| 243 |
+
'HAVE_GETLOADAVG': 1,
|
| 244 |
+
'HAVE_GETLOGIN': 1,
|
| 245 |
+
'HAVE_GETNAMEINFO': 1,
|
| 246 |
+
'HAVE_GETPAGESIZE': 1,
|
| 247 |
+
'HAVE_GETPEERNAME': 1,
|
| 248 |
+
'HAVE_GETPGID': 1,
|
| 249 |
+
'HAVE_GETPGRP': 1,
|
| 250 |
+
'HAVE_GETPID': 1,
|
| 251 |
+
'HAVE_GETPRIORITY': 1,
|
| 252 |
+
'HAVE_GETPWENT': 1,
|
| 253 |
+
'HAVE_GETRANDOM': 0,
|
| 254 |
+
'HAVE_GETRANDOM_SYSCALL': 0,
|
| 255 |
+
'HAVE_GETRESGID': 1,
|
| 256 |
+
'HAVE_GETRESUID': 1,
|
| 257 |
+
'HAVE_GETSID': 1,
|
| 258 |
+
'HAVE_GETSPENT': 1,
|
| 259 |
+
'HAVE_GETSPNAM': 1,
|
| 260 |
+
'HAVE_GETTIMEOFDAY': 1,
|
| 261 |
+
'HAVE_GETWD': 1,
|
| 262 |
+
'HAVE_GLIBC_MEMMOVE_BUG': 0,
|
| 263 |
+
'HAVE_GRP_H': 1,
|
| 264 |
+
'HAVE_HSTRERROR': 1,
|
| 265 |
+
'HAVE_HTOLE64': 1,
|
| 266 |
+
'HAVE_HYPOT': 1,
|
| 267 |
+
'HAVE_IEEEFP_H': 0,
|
| 268 |
+
'HAVE_IF_NAMEINDEX': 1,
|
| 269 |
+
'HAVE_INET_ATON': 1,
|
| 270 |
+
'HAVE_INET_PTON': 1,
|
| 271 |
+
'HAVE_INITGROUPS': 1,
|
| 272 |
+
'HAVE_INTTYPES_H': 1,
|
| 273 |
+
'HAVE_IO_H': 0,
|
| 274 |
+
'HAVE_IPA_PURE_CONST_BUG': 0,
|
| 275 |
+
'HAVE_KILL': 1,
|
| 276 |
+
'HAVE_KILLPG': 1,
|
| 277 |
+
'HAVE_KQUEUE': 0,
|
| 278 |
+
'HAVE_LANGINFO_H': 1,
|
| 279 |
+
'HAVE_LARGEFILE_SUPPORT': 0,
|
| 280 |
+
'HAVE_LCHFLAGS': 0,
|
| 281 |
+
'HAVE_LCHMOD': 0,
|
| 282 |
+
'HAVE_LCHOWN': 1,
|
| 283 |
+
'HAVE_LGAMMA': 1,
|
| 284 |
+
'HAVE_LIBDL': 1,
|
| 285 |
+
'HAVE_LIBDLD': 0,
|
| 286 |
+
'HAVE_LIBIEEE': 0,
|
| 287 |
+
'HAVE_LIBINTL_H': 1,
|
| 288 |
+
'HAVE_LIBREADLINE': 1,
|
| 289 |
+
'HAVE_LIBRESOLV': 0,
|
| 290 |
+
'HAVE_LIBSENDFILE': 0,
|
| 291 |
+
'HAVE_LIBUTIL_H': 0,
|
| 292 |
+
'HAVE_LINK': 1,
|
| 293 |
+
'HAVE_LINKAT': 1,
|
| 294 |
+
'HAVE_LINUX_CAN_BCM_H': 0,
|
| 295 |
+
'HAVE_LINUX_CAN_H': 1,
|
| 296 |
+
'HAVE_LINUX_CAN_RAW_FD_FRAMES': 0,
|
| 297 |
+
'HAVE_LINUX_CAN_RAW_H': 1,
|
| 298 |
+
'HAVE_LINUX_NETLINK_H': 1,
|
| 299 |
+
'HAVE_LINUX_RANDOM_H': 1,
|
| 300 |
+
'HAVE_LINUX_TIPC_H': 1,
|
| 301 |
+
'HAVE_LOCKF': 1,
|
| 302 |
+
'HAVE_LOG1P': 1,
|
| 303 |
+
'HAVE_LOG2': 1,
|
| 304 |
+
'HAVE_LONG_DOUBLE': 1,
|
| 305 |
+
'HAVE_LSTAT': 1,
|
| 306 |
+
'HAVE_LUTIMES': 1,
|
| 307 |
+
'HAVE_MAKEDEV': 1,
|
| 308 |
+
'HAVE_MBRTOWC': 1,
|
| 309 |
+
'HAVE_MEMMOVE': 1,
|
| 310 |
+
'HAVE_MEMORY_H': 1,
|
| 311 |
+
'HAVE_MEMRCHR': 1,
|
| 312 |
+
'HAVE_MKDIRAT': 1,
|
| 313 |
+
'HAVE_MKFIFO': 1,
|
| 314 |
+
'HAVE_MKFIFOAT': 1,
|
| 315 |
+
'HAVE_MKNOD': 1,
|
| 316 |
+
'HAVE_MKNODAT': 1,
|
| 317 |
+
'HAVE_MKTIME': 1,
|
| 318 |
+
'HAVE_MMAP': 1,
|
| 319 |
+
'HAVE_MREMAP': 1,
|
| 320 |
+
'HAVE_NCURSES_H': 1,
|
| 321 |
+
'HAVE_NDIR_H': 0,
|
| 322 |
+
'HAVE_NETPACKET_PACKET_H': 1,
|
| 323 |
+
'HAVE_NET_IF_H': 1,
|
| 324 |
+
'HAVE_NICE': 1,
|
| 325 |
+
'HAVE_OPENAT': 1,
|
| 326 |
+
'HAVE_OPENPTY': 1,
|
| 327 |
+
'HAVE_PATHCONF': 1,
|
| 328 |
+
'HAVE_PAUSE': 1,
|
| 329 |
+
'HAVE_PIPE2': 1,
|
| 330 |
+
'HAVE_PLOCK': 0,
|
| 331 |
+
'HAVE_POLL': 1,
|
| 332 |
+
'HAVE_POLL_H': 1,
|
| 333 |
+
'HAVE_POSIX_FADVISE': 1,
|
| 334 |
+
'HAVE_POSIX_FALLOCATE': 1,
|
| 335 |
+
'HAVE_PREAD': 1,
|
| 336 |
+
'HAVE_PRLIMIT': 0,
|
| 337 |
+
'HAVE_PROCESS_H': 0,
|
| 338 |
+
'HAVE_PROTOTYPES': 1,
|
| 339 |
+
'HAVE_PTHREAD_ATFORK': 1,
|
| 340 |
+
'HAVE_PTHREAD_DESTRUCTOR': 0,
|
| 341 |
+
'HAVE_PTHREAD_H': 1,
|
| 342 |
+
'HAVE_PTHREAD_INIT': 0,
|
| 343 |
+
'HAVE_PTHREAD_KILL': 1,
|
| 344 |
+
'HAVE_PTHREAD_SIGMASK': 1,
|
| 345 |
+
'HAVE_PTY_H': 1,
|
| 346 |
+
'HAVE_PUTENV': 1,
|
| 347 |
+
'HAVE_PWRITE': 1,
|
| 348 |
+
'HAVE_READLINK': 1,
|
| 349 |
+
'HAVE_READLINKAT': 1,
|
| 350 |
+
'HAVE_READV': 1,
|
| 351 |
+
'HAVE_REALPATH': 1,
|
| 352 |
+
'HAVE_RENAMEAT': 1,
|
| 353 |
+
'HAVE_RL_APPEND_HISTORY': 1,
|
| 354 |
+
'HAVE_RL_CALLBACK': 1,
|
| 355 |
+
'HAVE_RL_CATCH_SIGNAL': 1,
|
| 356 |
+
'HAVE_RL_COMPLETION_APPEND_CHARACTER': 1,
|
| 357 |
+
'HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK': 1,
|
| 358 |
+
'HAVE_RL_COMPLETION_MATCHES': 1,
|
| 359 |
+
'HAVE_RL_COMPLETION_SUPPRESS_APPEND': 1,
|
| 360 |
+
'HAVE_RL_PRE_INPUT_HOOK': 1,
|
| 361 |
+
'HAVE_RL_RESIZE_TERMINAL': 1,
|
| 362 |
+
'HAVE_ROUND': 1,
|
| 363 |
+
'HAVE_SCHED_GET_PRIORITY_MAX': 1,
|
| 364 |
+
'HAVE_SCHED_H': 1,
|
| 365 |
+
'HAVE_SCHED_RR_GET_INTERVAL': 1,
|
| 366 |
+
'HAVE_SCHED_SETAFFINITY': 1,
|
| 367 |
+
'HAVE_SCHED_SETPARAM': 1,
|
| 368 |
+
'HAVE_SCHED_SETSCHEDULER': 1,
|
| 369 |
+
'HAVE_SELECT': 1,
|
| 370 |
+
'HAVE_SEM_GETVALUE': 1,
|
| 371 |
+
'HAVE_SEM_OPEN': 1,
|
| 372 |
+
'HAVE_SEM_TIMEDWAIT': 1,
|
| 373 |
+
'HAVE_SEM_UNLINK': 1,
|
| 374 |
+
'HAVE_SENDFILE': 1,
|
| 375 |
+
'HAVE_SETEGID': 1,
|
| 376 |
+
'HAVE_SETEUID': 1,
|
| 377 |
+
'HAVE_SETGID': 1,
|
| 378 |
+
'HAVE_SETGROUPS': 1,
|
| 379 |
+
'HAVE_SETHOSTNAME': 1,
|
| 380 |
+
'HAVE_SETITIMER': 1,
|
| 381 |
+
'HAVE_SETLOCALE': 1,
|
| 382 |
+
'HAVE_SETPGID': 1,
|
| 383 |
+
'HAVE_SETPGRP': 1,
|
| 384 |
+
'HAVE_SETPRIORITY': 1,
|
| 385 |
+
'HAVE_SETREGID': 1,
|
| 386 |
+
'HAVE_SETRESGID': 1,
|
| 387 |
+
'HAVE_SETRESUID': 1,
|
| 388 |
+
'HAVE_SETREUID': 1,
|
| 389 |
+
'HAVE_SETSID': 1,
|
| 390 |
+
'HAVE_SETUID': 1,
|
| 391 |
+
'HAVE_SETVBUF': 1,
|
| 392 |
+
'HAVE_SHADOW_H': 1,
|
| 393 |
+
'HAVE_SIGACTION': 1,
|
| 394 |
+
'HAVE_SIGALTSTACK': 1,
|
| 395 |
+
'HAVE_SIGINTERRUPT': 1,
|
| 396 |
+
'HAVE_SIGNAL_H': 1,
|
| 397 |
+
'HAVE_SIGPENDING': 1,
|
| 398 |
+
'HAVE_SIGRELSE': 1,
|
| 399 |
+
'HAVE_SIGTIMEDWAIT': 1,
|
| 400 |
+
'HAVE_SIGWAIT': 1,
|
| 401 |
+
'HAVE_SIGWAITINFO': 1,
|
| 402 |
+
'HAVE_SNPRINTF': 1,
|
| 403 |
+
'HAVE_SOCKADDR_ALG': 0,
|
| 404 |
+
'HAVE_SOCKADDR_SA_LEN': 0,
|
| 405 |
+
'HAVE_SOCKADDR_STORAGE': 1,
|
| 406 |
+
'HAVE_SOCKETPAIR': 1,
|
| 407 |
+
'HAVE_SPAWN_H': 1,
|
| 408 |
+
'HAVE_SSIZE_T': 1,
|
| 409 |
+
'HAVE_STATVFS': 1,
|
| 410 |
+
'HAVE_STAT_TV_NSEC': 1,
|
| 411 |
+
'HAVE_STAT_TV_NSEC2': 0,
|
| 412 |
+
'HAVE_STDARG_PROTOTYPES': 1,
|
| 413 |
+
'HAVE_STDINT_H': 1,
|
| 414 |
+
'HAVE_STDLIB_H': 1,
|
| 415 |
+
'HAVE_STD_ATOMIC': 1,
|
| 416 |
+
'HAVE_STRDUP': 1,
|
| 417 |
+
'HAVE_STRFTIME': 1,
|
| 418 |
+
'HAVE_STRINGS_H': 1,
|
| 419 |
+
'HAVE_STRING_H': 1,
|
| 420 |
+
'HAVE_STRLCPY': 0,
|
| 421 |
+
'HAVE_STROPTS_H': 1,
|
| 422 |
+
'HAVE_STRUCT_PASSWD_PW_GECOS': 1,
|
| 423 |
+
'HAVE_STRUCT_PASSWD_PW_PASSWD': 1,
|
| 424 |
+
'HAVE_STRUCT_STAT_ST_BIRTHTIME': 0,
|
| 425 |
+
'HAVE_STRUCT_STAT_ST_BLKSIZE': 1,
|
| 426 |
+
'HAVE_STRUCT_STAT_ST_BLOCKS': 1,
|
| 427 |
+
'HAVE_STRUCT_STAT_ST_FLAGS': 0,
|
| 428 |
+
'HAVE_STRUCT_STAT_ST_GEN': 0,
|
| 429 |
+
'HAVE_STRUCT_STAT_ST_RDEV': 1,
|
| 430 |
+
'HAVE_STRUCT_TM_TM_ZONE': 1,
|
| 431 |
+
'HAVE_SYMLINK': 1,
|
| 432 |
+
'HAVE_SYMLINKAT': 1,
|
| 433 |
+
'HAVE_SYNC': 1,
|
| 434 |
+
'HAVE_SYSCONF': 1,
|
| 435 |
+
'HAVE_SYSEXITS_H': 1,
|
| 436 |
+
'HAVE_SYS_AUDIOIO_H': 0,
|
| 437 |
+
'HAVE_SYS_BSDTTY_H': 0,
|
| 438 |
+
'HAVE_SYS_DEVPOLL_H': 0,
|
| 439 |
+
'HAVE_SYS_DIR_H': 0,
|
| 440 |
+
'HAVE_SYS_ENDIAN_H': 0,
|
| 441 |
+
'HAVE_SYS_EPOLL_H': 1,
|
| 442 |
+
'HAVE_SYS_EVENT_H': 0,
|
| 443 |
+
'HAVE_SYS_FILE_H': 1,
|
| 444 |
+
'HAVE_SYS_IOCTL_H': 1,
|
| 445 |
+
'HAVE_SYS_KERN_CONTROL_H': 0,
|
| 446 |
+
'HAVE_SYS_LOADAVG_H': 0,
|
| 447 |
+
'HAVE_SYS_LOCK_H': 0,
|
| 448 |
+
'HAVE_SYS_MKDEV_H': 0,
|
| 449 |
+
'HAVE_SYS_MODEM_H': 0,
|
| 450 |
+
'HAVE_SYS_NDIR_H': 0,
|
| 451 |
+
'HAVE_SYS_PARAM_H': 1,
|
| 452 |
+
'HAVE_SYS_POLL_H': 1,
|
| 453 |
+
'HAVE_SYS_RANDOM_H': 0,
|
| 454 |
+
'HAVE_SYS_RESOURCE_H': 1,
|
| 455 |
+
'HAVE_SYS_SELECT_H': 1,
|
| 456 |
+
'HAVE_SYS_SENDFILE_H': 1,
|
| 457 |
+
'HAVE_SYS_SOCKET_H': 1,
|
| 458 |
+
'HAVE_SYS_STATVFS_H': 1,
|
| 459 |
+
'HAVE_SYS_STAT_H': 1,
|
| 460 |
+
'HAVE_SYS_SYSCALL_H': 1,
|
| 461 |
+
'HAVE_SYS_SYSMACROS_H': 1,
|
| 462 |
+
'HAVE_SYS_SYS_DOMAIN_H': 0,
|
| 463 |
+
'HAVE_SYS_TERMIO_H': 0,
|
| 464 |
+
'HAVE_SYS_TIMES_H': 1,
|
| 465 |
+
'HAVE_SYS_TIME_H': 1,
|
| 466 |
+
'HAVE_SYS_TYPES_H': 1,
|
| 467 |
+
'HAVE_SYS_UIO_H': 1,
|
| 468 |
+
'HAVE_SYS_UN_H': 1,
|
| 469 |
+
'HAVE_SYS_UTSNAME_H': 1,
|
| 470 |
+
'HAVE_SYS_WAIT_H': 1,
|
| 471 |
+
'HAVE_SYS_XATTR_H': 1,
|
| 472 |
+
'HAVE_TCGETPGRP': 1,
|
| 473 |
+
'HAVE_TCSETPGRP': 1,
|
| 474 |
+
'HAVE_TEMPNAM': 1,
|
| 475 |
+
'HAVE_TERMIOS_H': 1,
|
| 476 |
+
'HAVE_TERM_H': 1,
|
| 477 |
+
'HAVE_TGAMMA': 1,
|
| 478 |
+
'HAVE_TIMEGM': 1,
|
| 479 |
+
'HAVE_TIMES': 1,
|
| 480 |
+
'HAVE_TMPFILE': 1,
|
| 481 |
+
'HAVE_TMPNAM': 1,
|
| 482 |
+
'HAVE_TMPNAM_R': 1,
|
| 483 |
+
'HAVE_TM_ZONE': 1,
|
| 484 |
+
'HAVE_TRUNCATE': 1,
|
| 485 |
+
'HAVE_TZNAME': 0,
|
| 486 |
+
'HAVE_UCS4_TCL': 0,
|
| 487 |
+
'HAVE_UNAME': 1,
|
| 488 |
+
'HAVE_UNISTD_H': 1,
|
| 489 |
+
'HAVE_UNLINKAT': 1,
|
| 490 |
+
'HAVE_UNSETENV': 1,
|
| 491 |
+
'HAVE_USABLE_WCHAR_T': 0,
|
| 492 |
+
'HAVE_UTIL_H': 0,
|
| 493 |
+
'HAVE_UTIMENSAT': 1,
|
| 494 |
+
'HAVE_UTIMES': 1,
|
| 495 |
+
'HAVE_UTIME_H': 1,
|
| 496 |
+
'HAVE_WAIT3': 1,
|
| 497 |
+
'HAVE_WAIT4': 1,
|
| 498 |
+
'HAVE_WAITID': 1,
|
| 499 |
+
'HAVE_WAITPID': 1,
|
| 500 |
+
'HAVE_WCHAR_H': 1,
|
| 501 |
+
'HAVE_WCSCOLL': 1,
|
| 502 |
+
'HAVE_WCSFTIME': 1,
|
| 503 |
+
'HAVE_WCSXFRM': 1,
|
| 504 |
+
'HAVE_WMEMCMP': 1,
|
| 505 |
+
'HAVE_WORKING_TZSET': 1,
|
| 506 |
+
'HAVE_WRITEV': 1,
|
| 507 |
+
'HAVE_ZLIB_COPY': 1,
|
| 508 |
+
'HAVE__GETPTY': 0,
|
| 509 |
+
'HOST_GNU_TYPE': 's390x-conda-linux-gnu',
|
| 510 |
+
'INCLDIRSTOMAKE': '/workspace/anaconda3/include '
|
| 511 |
+
'/workspace/anaconda3/include '
|
| 512 |
+
'/workspace/anaconda3/include/python3.8 '
|
| 513 |
+
'/workspace/anaconda3/include/python3.8',
|
| 514 |
+
'INCLUDEDIR': '/workspace/anaconda3/include',
|
| 515 |
+
'INCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 516 |
+
'INSTALL': '/usr/bin/install -c',
|
| 517 |
+
'INSTALL_DATA': '/usr/bin/install -c -m 644',
|
| 518 |
+
'INSTALL_PROGRAM': '/usr/bin/install -c',
|
| 519 |
+
'INSTALL_SCRIPT': '/usr/bin/install -c',
|
| 520 |
+
'INSTALL_SHARED': '/usr/bin/install -c -m 555',
|
| 521 |
+
'INSTSONAME': 'libpython3.8.a',
|
| 522 |
+
'IO_H': 'Modules/_io/_iomodule.h',
|
| 523 |
+
'IO_OBJS': '\\',
|
| 524 |
+
'LDCXXSHARED': 's390x-conda-linux-gnu-c++ -pthread -shared',
|
| 525 |
+
'LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 526 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 527 |
+
'-L/workspace/anaconda3/lib '
|
| 528 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 529 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 530 |
+
'-L/workspace/anaconda3/lib '
|
| 531 |
+
' ',
|
| 532 |
+
'LDLAST': '',
|
| 533 |
+
'LDLIBRARY': 'libpython3.8.a',
|
| 534 |
+
'LDLIBRARYDIR': '',
|
| 535 |
+
'LDSHARED': 's390x-conda-linux-gnu-gcc -pthread -shared -Wl,-O2 '
|
| 536 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 537 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 538 |
+
'-L/workspace/anaconda3/lib '
|
| 539 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 540 |
+
'-Wl,-z,now '
|
| 541 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 542 |
+
'-L/workspace/anaconda3/lib '
|
| 543 |
+
' ',
|
| 544 |
+
'LDVERSION': '3.8',
|
| 545 |
+
'LIBC': '',
|
| 546 |
+
'LIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 547 |
+
'LIBDIR': '/workspace/anaconda3/lib',
|
| 548 |
+
'LIBFFI_INCLUDEDIR': '/workspace/anaconda3/include',
|
| 549 |
+
'LIBM': '-lm',
|
| 550 |
+
'LIBOBJDIR': 'Python/',
|
| 551 |
+
'LIBOBJS': '',
|
| 552 |
+
'LIBPC': '/workspace/anaconda3/lib/pkgconfig',
|
| 553 |
+
'LIBPL': '/workspace/anaconda3/lib/python3.8/config-3.8-s390x-linux-gnu',
|
| 554 |
+
'LIBRARY': 'libpython3.8.a',
|
| 555 |
+
'LIBRARY_OBJS': '\\',
|
| 556 |
+
'LIBRARY_OBJS_OMIT_FROZEN': '\\',
|
| 557 |
+
'LIBS': '-lpthread -ldl -lutil -lrt',
|
| 558 |
+
'LIBSUBDIRS': 'tkinter tkinter/test tkinter/test/test_tkinter \\',
|
| 559 |
+
'LINKCC': 's390x-conda-linux-gnu-gcc -pthread',
|
| 560 |
+
'LINKFORSHARED': '-Xlinker -export-dynamic',
|
| 561 |
+
'LIPO_32BIT_FLAGS': '',
|
| 562 |
+
'LLVM_PROF_ERR': 'no',
|
| 563 |
+
'LLVM_PROF_FILE': '',
|
| 564 |
+
'LLVM_PROF_MERGER': 'true',
|
| 565 |
+
'LN': 'ln',
|
| 566 |
+
'LOCALMODLIBS': '',
|
| 567 |
+
'LOG1P_DROPS_ZERO_SIGN': 0,
|
| 568 |
+
'MACHDEP': 'linux',
|
| 569 |
+
'MACHDEPPATH': ':',
|
| 570 |
+
'MACHDEP_OBJS': '',
|
| 571 |
+
'MACHDESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 572 |
+
'MACOSX_DEPLOYMENT_TARGET': '',
|
| 573 |
+
'MAINCC': 's390x-conda-linux-gnu-gcc -pthread',
|
| 574 |
+
'MAJOR_IN_MKDEV': 0,
|
| 575 |
+
'MAJOR_IN_SYSMACROS': 0,
|
| 576 |
+
'MAKESETUP': '/tmp/build/80754af9/python_1510184704423/work/Modules/makesetup',
|
| 577 |
+
'MANDIR': '/workspace/anaconda3/share/man',
|
| 578 |
+
'MKDIR_P': '/bin/mkdir -p',
|
| 579 |
+
'MODLIBS': '',
|
| 580 |
+
'MODNAMES': '_thread posix errno pwd _sre _codecs _weakref _functools '
|
| 581 |
+
'_operator _collections itertools atexit _signal _stat time '
|
| 582 |
+
'_locale _io zipimport faulthandler _tracemalloc _symtable '
|
| 583 |
+
'xxsubtype',
|
| 584 |
+
'MODOBJS': 'Modules/_threadmodule.o Modules/posixmodule.o '
|
| 585 |
+
'Modules/errnomodule.o Modules/pwdmodule.o Modules/_sre.o '
|
| 586 |
+
'Modules/_codecsmodule.o Modules/_weakref.o '
|
| 587 |
+
'Modules/_functoolsmodule.o Modules/_operator.o '
|
| 588 |
+
'Modules/_collectionsmodule.o Modules/itertoolsmodule.o '
|
| 589 |
+
'Modules/atexitmodule.o Modules/signalmodule.o Modules/_stat.o '
|
| 590 |
+
'Modules/timemodule.o Modules/_localemodule.o '
|
| 591 |
+
'Modules/_iomodule.o Modules/iobase.o Modules/fileio.o '
|
| 592 |
+
'Modules/bytesio.o Modules/bufferedio.o Modules/textio.o '
|
| 593 |
+
'Modules/stringio.o Modules/zipimport.o Modules/faulthandler.o '
|
| 594 |
+
'Modules/_tracemalloc.o Modules/hashtable.o '
|
| 595 |
+
'Modules/symtablemodule.o Modules/xxsubtype.o',
|
| 596 |
+
'MODULE_OBJS': '\\',
|
| 597 |
+
'MULTIARCH': 's390x-linux-gnu',
|
| 598 |
+
'MULTIARCH_CPPFLAGS': '-DMULTIARCH=\\"s390x-linux-gnu\\"',
|
| 599 |
+
'MVWDELCH_IS_EXPRESSION': 1,
|
| 600 |
+
'NO_AS_NEEDED': '-Wl,--no-as-needed',
|
| 601 |
+
'OBJECT_OBJS': '\\',
|
| 602 |
+
'OPT': '-DNDEBUG -fwrapv -O2 -Wall -Wstrict-prototypes',
|
| 603 |
+
'OTHER_LIBTOOL_OPT': '',
|
| 604 |
+
'PACKAGE_BUGREPORT': 0,
|
| 605 |
+
'PACKAGE_NAME': 0,
|
| 606 |
+
'PACKAGE_STRING': 0,
|
| 607 |
+
'PACKAGE_TARNAME': 0,
|
| 608 |
+
'PACKAGE_URL': 0,
|
| 609 |
+
'PACKAGE_VERSION': 0,
|
| 610 |
+
'PARSER_HEADERS': '\\',
|
| 611 |
+
'PARSER_OBJS': '\\ Parser/myreadline.o Parser/parsetok.o Parser/tokenizer.o',
|
| 612 |
+
'PGEN': 'Parser/pgen',
|
| 613 |
+
'PGENOBJS': '\\ \\',
|
| 614 |
+
'PGOBJS': '\\',
|
| 615 |
+
'PGO_PROF_GEN_FLAG': '-fprofile-generate',
|
| 616 |
+
'PGO_PROF_USE_FLAG': ' ',
|
| 617 |
+
'PLATDIR': '',
|
| 618 |
+
'POBJS': '\\',
|
| 619 |
+
'POSIX_SEMAPHORES_NOT_ENABLED': 0,
|
| 620 |
+
'PROFILE_TASK': '-m test.regrtest --pgo',
|
| 621 |
+
'PTHREAD_SYSTEM_SCHED_SUPPORTED': 1,
|
| 622 |
+
'PURIFY': '',
|
| 623 |
+
'PY3LIBRARY': '',
|
| 624 |
+
'PYLONG_BITS_IN_DIGIT': 0,
|
| 625 |
+
'PYTHON': 'python',
|
| 626 |
+
'PYTHONFRAMEWORK': '',
|
| 627 |
+
'PYTHONFRAMEWORKDIR': 'no-framework',
|
| 628 |
+
'PYTHONFRAMEWORKINSTALLDIR': '',
|
| 629 |
+
'PYTHONFRAMEWORKPREFIX': '',
|
| 630 |
+
'PYTHONPATH': ':',
|
| 631 |
+
'PYTHON_FOR_BUILD': './python -E',
|
| 632 |
+
'PYTHON_FOR_REGEN': 'python3.8',
|
| 633 |
+
'PYTHON_HEADERS': '\\',
|
| 634 |
+
'PYTHON_OBJS': '\\',
|
| 635 |
+
'PY_BUILD_ENVIRON': '',
|
| 636 |
+
'PY_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall '
|
| 637 |
+
'-Wstrict-prototypes -march=z14 -mtune=z14 '
|
| 638 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 '
|
| 639 |
+
'-pipe '
|
| 640 |
+
' -march=z14 -mtune=z14 '
|
| 641 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 '
|
| 642 |
+
'-pipe '
|
| 643 |
+
' ',
|
| 644 |
+
'PY_CFLAGS_NODIST': '-std=c99 -Wextra -Wno-unused-result '
|
| 645 |
+
'-Wno-unused-parameter -Wno-missing-field-initializers '
|
| 646 |
+
'-march=z14 -mtune=z14 -ftree-vectorize -fPIC '
|
| 647 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 648 |
+
' '
|
| 649 |
+
' '
|
| 650 |
+
' '
|
| 651 |
+
' ',
|
| 652 |
+
'PY_CORE_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 '
|
| 653 |
+
'-Wall -Wstrict-prototypes -march=z14 -mtune=z14 '
|
| 654 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt '
|
| 655 |
+
'-O2 -pipe '
|
| 656 |
+
' -march=z14 -mtune=z14 '
|
| 657 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt '
|
| 658 |
+
'-O2 -pipe '
|
| 659 |
+
' -std=c99 -Wextra '
|
| 660 |
+
'-Wno-unused-result -Wno-unused-parameter '
|
| 661 |
+
'-Wno-missing-field-initializers -march=z14 '
|
| 662 |
+
'-mtune=z14 -ftree-vectorize -fPIC '
|
| 663 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 664 |
+
' '
|
| 665 |
+
' '
|
| 666 |
+
' '
|
| 667 |
+
'-IObjects -IInclude -IPython -I. '
|
| 668 |
+
'-I/tmp/build/80754af9/python_1510184704423/work/Include '
|
| 669 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 670 |
+
'-I/workspace/anaconda3/include '
|
| 671 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 672 |
+
'-I/workspace/anaconda3/include '
|
| 673 |
+
'-DPy_BUILD_CORE',
|
| 674 |
+
'PY_CPPFLAGS': '-IObjects -IInclude -IPython -I. '
|
| 675 |
+
'-I/tmp/build/80754af9/python_1510184704423/work/Include '
|
| 676 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 677 |
+
'-I/workspace/anaconda3/include '
|
| 678 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 679 |
+
'-I/workspace/anaconda3/include',
|
| 680 |
+
'PY_FORMAT_SIZE_T': '"z"',
|
| 681 |
+
'PY_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 682 |
+
'-Wl,-z,now '
|
| 683 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 684 |
+
'-L/workspace/anaconda3/lib '
|
| 685 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 686 |
+
'-Wl,-z,now '
|
| 687 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 688 |
+
'-L/workspace/anaconda3/lib '
|
| 689 |
+
' '
|
| 690 |
+
'',
|
| 691 |
+
'Py_DEBUG': 0,
|
| 692 |
+
'Py_ENABLE_SHARED': 0,
|
| 693 |
+
'Py_HASH_ALGORITHM': 0,
|
| 694 |
+
'QUICKTESTOPTS': '-x test_subprocess test_io test_lib2to3 \\',
|
| 695 |
+
'RANLIB': 's390x-conda-linux-gnu-ranlib',
|
| 696 |
+
'READELF': 's390x-conda-linux-gnu-readelf',
|
| 697 |
+
'RESSRCDIR': 'Mac/Resources/framework',
|
| 698 |
+
'RETSIGTYPE': 'void',
|
| 699 |
+
'RUNSHARED': '',
|
| 700 |
+
'SCRIPTDIR': '/workspace/anaconda3/lib',
|
| 701 |
+
'SETPGRP_HAVE_ARG': 0,
|
| 702 |
+
'SGI_ABI': '',
|
| 703 |
+
'SHELL': '/bin/sh',
|
| 704 |
+
'SHLIBS': '-lpthread -ldl -lutil -lrt',
|
| 705 |
+
'SHLIB_SUFFIX': '.so',
|
| 706 |
+
'SIGNED_RIGHT_SHIFT_ZERO_FILLS': 0,
|
| 707 |
+
'SITEPATH': '',
|
| 708 |
+
'SIZEOF_DOUBLE': 8,
|
| 709 |
+
'SIZEOF_FLOAT': 4,
|
| 710 |
+
'SIZEOF_FPOS_T': 16,
|
| 711 |
+
'SIZEOF_INT': 4,
|
| 712 |
+
'SIZEOF_LONG': 8,
|
| 713 |
+
'SIZEOF_LONG_DOUBLE': 16,
|
| 714 |
+
'SIZEOF_LONG_LONG': 8,
|
| 715 |
+
'SIZEOF_OFF_T': 8,
|
| 716 |
+
'SIZEOF_PID_T': 4,
|
| 717 |
+
'SIZEOF_PTHREAD_T': 8,
|
| 718 |
+
'SIZEOF_SHORT': 2,
|
| 719 |
+
'SIZEOF_SIZE_T': 8,
|
| 720 |
+
'SIZEOF_TIME_T': 8,
|
| 721 |
+
'SIZEOF_UINTPTR_T': 8,
|
| 722 |
+
'SIZEOF_VOID_P': 8,
|
| 723 |
+
'SIZEOF_WCHAR_T': 4,
|
| 724 |
+
'SIZEOF__BOOL': 1,
|
| 725 |
+
'SOABI': 'cpython-38-s390x-linux-gnu',
|
| 726 |
+
'SRCDIRS': 'Parser Grammar Objects Python Modules Mac Programs',
|
| 727 |
+
'SRC_GDB_HOOKS': '/tmp/build/80754af9/python_1510184704423/work/Tools/gdb/libpython.py',
|
| 728 |
+
'STDC_HEADERS': 1,
|
| 729 |
+
'STRICT_SYSV_CURSES': "/* Don't use ncurses extensions */",
|
| 730 |
+
'STRIPFLAG': '-s',
|
| 731 |
+
'SUBDIRS': '',
|
| 732 |
+
'SUBDIRSTOO': 'Include Lib Misc',
|
| 733 |
+
'SYSLIBS': '-lm',
|
| 734 |
+
'SYS_SELECT_WITH_SYS_TIME': 1,
|
| 735 |
+
'TANH_PRESERVES_ZERO_SIGN': 1,
|
| 736 |
+
'TCLTK_INCLUDES': '-I/workspace/anaconda3/include',
|
| 737 |
+
'TCLTK_LIBS': '-L/workspace/anaconda3/lib '
|
| 738 |
+
'-ltcl8.6 -ltk8.6',
|
| 739 |
+
'TESTOPTS': '',
|
| 740 |
+
'TESTPATH': '',
|
| 741 |
+
'TESTPYTHON': './python',
|
| 742 |
+
'TESTPYTHONOPTS': '',
|
| 743 |
+
'TESTRUNNER': './python '
|
| 744 |
+
'/tmp/build/80754af9/python_1510184704423/work/Tools/scripts/run_tests.py',
|
| 745 |
+
'TESTTIMEOUT': 1200,
|
| 746 |
+
'THREADOBJ': 'Python/thread.o',
|
| 747 |
+
'TIMEMODULE_LIB': 'rt',
|
| 748 |
+
'TIME_WITH_SYS_TIME': 1,
|
| 749 |
+
'TM_IN_SYS_TIME': 0,
|
| 750 |
+
'UNICODE_DEPS': '\\',
|
| 751 |
+
'UNIVERSALSDK': '',
|
| 752 |
+
'USE_COMPUTED_GOTOS': 1,
|
| 753 |
+
'USE_INLINE': 1,
|
| 754 |
+
'VERSION': '3.8',
|
| 755 |
+
'VPATH': '/tmp/build/80754af9/python_1510184704423/work',
|
| 756 |
+
'WANT_SIGFPE_HANDLER': 0,
|
| 757 |
+
'WINDOW_HAS_FLAGS': 1,
|
| 758 |
+
'WITH_DOC_STRINGS': 1,
|
| 759 |
+
'WITH_DTRACE': 0,
|
| 760 |
+
'WITH_DYLD': 0,
|
| 761 |
+
'WITH_LIBINTL': 0,
|
| 762 |
+
'WITH_NEXT_FRAMEWORK': 0,
|
| 763 |
+
'WITH_PYMALLOC': 1,
|
| 764 |
+
'WITH_THREAD': 1,
|
| 765 |
+
'WITH_VALGRIND': 0,
|
| 766 |
+
'X87_DOUBLE_ROUNDING': 0,
|
| 767 |
+
'XMLLIBSUBDIRS': 'xml xml/dom xml/etree xml/parsers xml/sax',
|
| 768 |
+
'abs_builddir': '/tmp/build/80754af9/python_1510184704423/work/build-static',
|
| 769 |
+
'abs_srcdir': '/tmp/build/80754af9/python_1510184704423/work',
|
| 770 |
+
'datarootdir': '/workspace/anaconda3/share',
|
| 771 |
+
'exec_prefix': '/workspace/anaconda3',
|
| 772 |
+
'prefix': '/workspace/anaconda3',
|
| 773 |
+
'srcdir': '/tmp/build/80754af9/python_1510184704423/work'}
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata_x86_64_conda_cos7_linux_gnu.py
ADDED
|
@@ -0,0 +1,773 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# system configuration generated and used by the sysconfig module
|
| 2 |
+
build_time_vars = {'ABIFLAGS': '',
|
| 3 |
+
'AC_APPLE_UNIVERSAL_BUILD': 0,
|
| 4 |
+
'AIX_GENUINE_CPLUSPLUS': 0,
|
| 5 |
+
'ANDROID_API_LEVEL': 0,
|
| 6 |
+
'AR': 'x86_64-conda_cos7-linux-gnu-ar',
|
| 7 |
+
'ARFLAGS': 'rc',
|
| 8 |
+
'BASECFLAGS': '-Wno-unused-result -Wsign-compare',
|
| 9 |
+
'BASECPPFLAGS': '-IObjects -IInclude -IPython',
|
| 10 |
+
'BASEMODLIBS': '',
|
| 11 |
+
'BINDIR': '/workspace/anaconda3/bin',
|
| 12 |
+
'BINLIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 13 |
+
'BLDLIBRARY': 'libpython3.8.a',
|
| 14 |
+
'BLDSHARED': 'x86_64-conda_cos7-linux-gnu-gcc -pthread -shared -Wl,-O2 '
|
| 15 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 16 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 17 |
+
'-L/workspace/anaconda3/lib '
|
| 18 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 19 |
+
'-Wl,-z,now '
|
| 20 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 21 |
+
'-L/workspace/anaconda3/lib '
|
| 22 |
+
' '
|
| 23 |
+
'',
|
| 24 |
+
'BUILDEXE': '',
|
| 25 |
+
'BUILDPYTHON': 'python',
|
| 26 |
+
'BUILD_GNU_TYPE': 'x86_64-conda_cos7-linux-gnu',
|
| 27 |
+
'BYTESTR_DEPS': '\\',
|
| 28 |
+
'CC': 'x86_64-conda_cos7-linux-gnu-gcc -pthread',
|
| 29 |
+
'CCSHARED': '-fPIC',
|
| 30 |
+
'CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall '
|
| 31 |
+
'-Wstrict-prototypes -march=nocona -mtune=haswell -ftree-vectorize '
|
| 32 |
+
'-fPIC -fstack-protector-strong -fno-plt -O2 -pipe '
|
| 33 |
+
' '
|
| 34 |
+
'-march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 35 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 36 |
+
' ',
|
| 37 |
+
'CFLAGSFORSHARED': '',
|
| 38 |
+
'CFLAGS_ALIASING': '',
|
| 39 |
+
'CONFIGFILES': 'configure configure.ac acconfig.h pyconfig.h.in '
|
| 40 |
+
'Makefile.pre.in',
|
| 41 |
+
'CONFIGURE_CFLAGS': '-march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 42 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 43 |
+
' '
|
| 44 |
+
' ',
|
| 45 |
+
'CONFIGURE_CFLAGS_NODIST': '-std=c99 -Wextra -Wno-unused-result '
|
| 46 |
+
'-Wno-unused-parameter '
|
| 47 |
+
'-Wno-missing-field-initializers',
|
| 48 |
+
'CONFIGURE_CPPFLAGS': '-D_FORTIFY_SOURCE=2 -O2 '
|
| 49 |
+
'-I/workspace/anaconda3/include',
|
| 50 |
+
'CONFIGURE_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 51 |
+
'-Wl,-z,now '
|
| 52 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 53 |
+
'-L/workspace/anaconda3/lib',
|
| 54 |
+
'CONFIG_ARGS': "'--prefix=/workspace/anaconda3' "
|
| 55 |
+
"'--build=x86_64-conda_cos7-linux-gnu' "
|
| 56 |
+
"'--host=x86_64-conda_cos7-linux-gnu' '--enable-ipv6' "
|
| 57 |
+
"'--with-ensurepip=no' '--with-computed-gotos' "
|
| 58 |
+
"'--with-system-ffi' '--enable-loadable-sqlite-extensions' "
|
| 59 |
+
"'--with-tcltk-includes=-I/workspace/anaconda3/include' "
|
| 60 |
+
"'--with-tcltk-libs=-L/workspace/anaconda3/lib "
|
| 61 |
+
"-ltcl8.6 -ltk8.6' '--enable-optimizations' '--with-lto' "
|
| 62 |
+
"'--disable-shared' 'build_alias=x86_64-conda_cos7-linux-gnu' "
|
| 63 |
+
"'host_alias=x86_64-conda_cos7-linux-gnu' "
|
| 64 |
+
"'CC=x86_64-conda_cos7-linux-gnu-gcc' 'CFLAGS=-march=nocona "
|
| 65 |
+
'-mtune=haswell -ftree-vectorize -fPIC '
|
| 66 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 67 |
+
' '
|
| 68 |
+
"' 'LDFLAGS=-Wl,-O2 -Wl,--sort-common -Wl,--as-needed "
|
| 69 |
+
'-Wl,-z,relro -Wl,-z,now '
|
| 70 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 71 |
+
"-L/workspace/anaconda3/lib' "
|
| 72 |
+
"'CPPFLAGS=-D_FORTIFY_SOURCE=2 -O2 "
|
| 73 |
+
"-I/workspace/anaconda3/include' "
|
| 74 |
+
"'CPP=/workspace/anaconda3/bin/x86_64-conda_cos7-linux-gnu-cpp' "
|
| 75 |
+
"'PKG_CONFIG_PATH=/workspace/anaconda3/lib/pkgconfig'",
|
| 76 |
+
'CONFINCLUDEDIR': '/workspace/anaconda3/include',
|
| 77 |
+
'CONFINCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 78 |
+
'COREPYTHONPATH': ':',
|
| 79 |
+
'COVERAGE_INFO': '/tmp/build/80754af9/python_1510184704423/work/build-static/coverage.info',
|
| 80 |
+
'COVERAGE_REPORT': '/tmp/build/80754af9/python_1510184704423/work/build-static/lcov-report',
|
| 81 |
+
'COVERAGE_REPORT_OPTIONS': '--no-branch-coverage --title "CPython lcov '
|
| 82 |
+
'report"',
|
| 83 |
+
'CPPFLAGS': '-IObjects -IInclude -IPython -I. '
|
| 84 |
+
'-I/tmp/build/80754af9/python_1510184704423/work/Include '
|
| 85 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 86 |
+
'-I/workspace/anaconda3/include '
|
| 87 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 88 |
+
'-I/workspace/anaconda3/include',
|
| 89 |
+
'CXX': 'x86_64-conda_cos7-linux-gnu-c++ -pthread',
|
| 90 |
+
'DESTDIRS': '/workspace/anaconda3 '
|
| 91 |
+
'/workspace/anaconda3/lib '
|
| 92 |
+
'/workspace/anaconda3/lib/python3.8 '
|
| 93 |
+
'/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 94 |
+
'DESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 95 |
+
'DESTPATH': '',
|
| 96 |
+
'DESTSHARED': '/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 97 |
+
'DFLAGS': '',
|
| 98 |
+
'DIRMODE': 755,
|
| 99 |
+
'DIST': 'README ChangeLog configure configure.ac acconfig.h pyconfig.h.in '
|
| 100 |
+
'Makefile.pre.in Include Lib Misc Ext-dummy',
|
| 101 |
+
'DISTDIRS': 'Include Lib Misc Ext-dummy',
|
| 102 |
+
'DISTFILES': 'README ChangeLog configure configure.ac acconfig.h '
|
| 103 |
+
'pyconfig.h.in Makefile.pre.in',
|
| 104 |
+
'DLINCLDIR': '.',
|
| 105 |
+
'DLLLIBRARY': '',
|
| 106 |
+
'DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754': 0,
|
| 107 |
+
'DOUBLE_IS_BIG_ENDIAN_IEEE754': 0,
|
| 108 |
+
'DOUBLE_IS_LITTLE_ENDIAN_IEEE754': 1,
|
| 109 |
+
'DTRACE': '',
|
| 110 |
+
'DTRACE_DEPS': '\\',
|
| 111 |
+
'DTRACE_HEADERS': '',
|
| 112 |
+
'DTRACE_OBJS': '',
|
| 113 |
+
'DYNLOADFILE': 'dynload_shlib.o',
|
| 114 |
+
'ENABLE_IPV6': 1,
|
| 115 |
+
'ENSUREPIP': 'no',
|
| 116 |
+
'EXE': '',
|
| 117 |
+
'EXEMODE': 755,
|
| 118 |
+
'EXTRAMACHDEPPATH': '',
|
| 119 |
+
'EXTRATESTOPTS': '',
|
| 120 |
+
'EXT_SUFFIX': '.cpython-38-x86_64-linux-gnu.so',
|
| 121 |
+
'FILEMODE': 644,
|
| 122 |
+
'FLOCK_NEEDS_LIBBSD': 0,
|
| 123 |
+
'GETPGRP_HAVE_ARG': 0,
|
| 124 |
+
'GETTIMEOFDAY_NO_TZ': 0,
|
| 125 |
+
'GITBRANCH': '',
|
| 126 |
+
'GITTAG': '',
|
| 127 |
+
'GITVERSION': '',
|
| 128 |
+
'GNULD': 'yes',
|
| 129 |
+
'HAVE_ACCEPT4': 1,
|
| 130 |
+
'HAVE_ACOSH': 1,
|
| 131 |
+
'HAVE_ADDRINFO': 1,
|
| 132 |
+
'HAVE_ALARM': 1,
|
| 133 |
+
'HAVE_ALIGNED_REQUIRED': 0,
|
| 134 |
+
'HAVE_ALLOCA_H': 1,
|
| 135 |
+
'HAVE_ALTZONE': 0,
|
| 136 |
+
'HAVE_ASINH': 1,
|
| 137 |
+
'HAVE_ASM_TYPES_H': 1,
|
| 138 |
+
'HAVE_ATANH': 1,
|
| 139 |
+
'HAVE_BIND_TEXTDOMAIN_CODESET': 1,
|
| 140 |
+
'HAVE_BLUETOOTH_BLUETOOTH_H': 0,
|
| 141 |
+
'HAVE_BLUETOOTH_H': 0,
|
| 142 |
+
'HAVE_BROKEN_MBSTOWCS': 0,
|
| 143 |
+
'HAVE_BROKEN_NICE': 0,
|
| 144 |
+
'HAVE_BROKEN_PIPE_BUF': 0,
|
| 145 |
+
'HAVE_BROKEN_POLL': 0,
|
| 146 |
+
'HAVE_BROKEN_POSIX_SEMAPHORES': 0,
|
| 147 |
+
'HAVE_BROKEN_PTHREAD_SIGMASK': 0,
|
| 148 |
+
'HAVE_BROKEN_SEM_GETVALUE': 0,
|
| 149 |
+
'HAVE_BROKEN_UNSETENV': 0,
|
| 150 |
+
'HAVE_BUILTIN_ATOMIC': 1,
|
| 151 |
+
'HAVE_CHFLAGS': 0,
|
| 152 |
+
'HAVE_CHOWN': 1,
|
| 153 |
+
'HAVE_CHROOT': 1,
|
| 154 |
+
'HAVE_CLOCK': 1,
|
| 155 |
+
'HAVE_CLOCK_GETRES': 1,
|
| 156 |
+
'HAVE_CLOCK_GETTIME': 1,
|
| 157 |
+
'HAVE_CLOCK_SETTIME': 1,
|
| 158 |
+
'HAVE_COMPUTED_GOTOS': 1,
|
| 159 |
+
'HAVE_CONFSTR': 1,
|
| 160 |
+
'HAVE_CONIO_H': 0,
|
| 161 |
+
'HAVE_COPYSIGN': 1,
|
| 162 |
+
'HAVE_CTERMID': 1,
|
| 163 |
+
'HAVE_CTERMID_R': 0,
|
| 164 |
+
'HAVE_CURSES_H': 1,
|
| 165 |
+
'HAVE_CURSES_IS_TERM_RESIZED': 1,
|
| 166 |
+
'HAVE_CURSES_RESIZETERM': 1,
|
| 167 |
+
'HAVE_CURSES_RESIZE_TERM': 1,
|
| 168 |
+
'HAVE_DECL_ISFINITE': 1,
|
| 169 |
+
'HAVE_DECL_ISINF': 1,
|
| 170 |
+
'HAVE_DECL_ISNAN': 1,
|
| 171 |
+
'HAVE_DECL_RTLD_DEEPBIND': 1,
|
| 172 |
+
'HAVE_DECL_RTLD_GLOBAL': 1,
|
| 173 |
+
'HAVE_DECL_RTLD_LAZY': 1,
|
| 174 |
+
'HAVE_DECL_RTLD_LOCAL': 1,
|
| 175 |
+
'HAVE_DECL_RTLD_NODELETE': 1,
|
| 176 |
+
'HAVE_DECL_RTLD_NOLOAD': 1,
|
| 177 |
+
'HAVE_DECL_RTLD_NOW': 1,
|
| 178 |
+
'HAVE_DECL_TZNAME': 0,
|
| 179 |
+
'HAVE_DEVICE_MACROS': 1,
|
| 180 |
+
'HAVE_DEV_PTC': 0,
|
| 181 |
+
'HAVE_DEV_PTMX': 1,
|
| 182 |
+
'HAVE_DIRECT_H': 0,
|
| 183 |
+
'HAVE_DIRENT_D_TYPE': 1,
|
| 184 |
+
'HAVE_DIRENT_H': 1,
|
| 185 |
+
'HAVE_DIRFD': 1,
|
| 186 |
+
'HAVE_DLFCN_H': 1,
|
| 187 |
+
'HAVE_DLOPEN': 1,
|
| 188 |
+
'HAVE_DUP2': 1,
|
| 189 |
+
'HAVE_DUP3': 1,
|
| 190 |
+
'HAVE_DYNAMIC_LOADING': 1,
|
| 191 |
+
'HAVE_ENDIAN_H': 1,
|
| 192 |
+
'HAVE_EPOLL': 1,
|
| 193 |
+
'HAVE_EPOLL_CREATE1': 1,
|
| 194 |
+
'HAVE_ERF': 1,
|
| 195 |
+
'HAVE_ERFC': 1,
|
| 196 |
+
'HAVE_ERRNO_H': 1,
|
| 197 |
+
'HAVE_EXECV': 1,
|
| 198 |
+
'HAVE_EXPM1': 1,
|
| 199 |
+
'HAVE_FACCESSAT': 1,
|
| 200 |
+
'HAVE_FCHDIR': 1,
|
| 201 |
+
'HAVE_FCHMOD': 1,
|
| 202 |
+
'HAVE_FCHMODAT': 1,
|
| 203 |
+
'HAVE_FCHOWN': 1,
|
| 204 |
+
'HAVE_FCHOWNAT': 1,
|
| 205 |
+
'HAVE_FCNTL_H': 1,
|
| 206 |
+
'HAVE_FDATASYNC': 1,
|
| 207 |
+
'HAVE_FDOPENDIR': 1,
|
| 208 |
+
'HAVE_FEXECVE': 1,
|
| 209 |
+
'HAVE_FINITE': 1,
|
| 210 |
+
'HAVE_FLOCK': 1,
|
| 211 |
+
'HAVE_FORK': 1,
|
| 212 |
+
'HAVE_FORKPTY': 1,
|
| 213 |
+
'HAVE_FPATHCONF': 1,
|
| 214 |
+
'HAVE_FSEEK64': 0,
|
| 215 |
+
'HAVE_FSEEKO': 1,
|
| 216 |
+
'HAVE_FSTATAT': 1,
|
| 217 |
+
'HAVE_FSTATVFS': 1,
|
| 218 |
+
'HAVE_FSYNC': 1,
|
| 219 |
+
'HAVE_FTELL64': 0,
|
| 220 |
+
'HAVE_FTELLO': 1,
|
| 221 |
+
'HAVE_FTIME': 1,
|
| 222 |
+
'HAVE_FTRUNCATE': 1,
|
| 223 |
+
'HAVE_FUTIMENS': 1,
|
| 224 |
+
'HAVE_FUTIMES': 1,
|
| 225 |
+
'HAVE_FUTIMESAT': 1,
|
| 226 |
+
'HAVE_GAI_STRERROR': 1,
|
| 227 |
+
'HAVE_GAMMA': 1,
|
| 228 |
+
'HAVE_GCC_ASM_FOR_MC68881': 0,
|
| 229 |
+
'HAVE_GCC_ASM_FOR_X64': 1,
|
| 230 |
+
'HAVE_GCC_ASM_FOR_X87': 1,
|
| 231 |
+
'HAVE_GCC_UINT128_T': 1,
|
| 232 |
+
'HAVE_GETADDRINFO': 1,
|
| 233 |
+
'HAVE_GETC_UNLOCKED': 1,
|
| 234 |
+
'HAVE_GETENTROPY': 0,
|
| 235 |
+
'HAVE_GETGROUPLIST': 1,
|
| 236 |
+
'HAVE_GETGROUPS': 1,
|
| 237 |
+
'HAVE_GETHOSTBYNAME': 0,
|
| 238 |
+
'HAVE_GETHOSTBYNAME_R': 1,
|
| 239 |
+
'HAVE_GETHOSTBYNAME_R_3_ARG': 0,
|
| 240 |
+
'HAVE_GETHOSTBYNAME_R_5_ARG': 0,
|
| 241 |
+
'HAVE_GETHOSTBYNAME_R_6_ARG': 1,
|
| 242 |
+
'HAVE_GETITIMER': 1,
|
| 243 |
+
'HAVE_GETLOADAVG': 1,
|
| 244 |
+
'HAVE_GETLOGIN': 1,
|
| 245 |
+
'HAVE_GETNAMEINFO': 1,
|
| 246 |
+
'HAVE_GETPAGESIZE': 1,
|
| 247 |
+
'HAVE_GETPEERNAME': 1,
|
| 248 |
+
'HAVE_GETPGID': 1,
|
| 249 |
+
'HAVE_GETPGRP': 1,
|
| 250 |
+
'HAVE_GETPID': 1,
|
| 251 |
+
'HAVE_GETPRIORITY': 1,
|
| 252 |
+
'HAVE_GETPWENT': 1,
|
| 253 |
+
'HAVE_GETRANDOM': 0,
|
| 254 |
+
'HAVE_GETRANDOM_SYSCALL': 0,
|
| 255 |
+
'HAVE_GETRESGID': 1,
|
| 256 |
+
'HAVE_GETRESUID': 1,
|
| 257 |
+
'HAVE_GETSID': 1,
|
| 258 |
+
'HAVE_GETSPENT': 1,
|
| 259 |
+
'HAVE_GETSPNAM': 1,
|
| 260 |
+
'HAVE_GETTIMEOFDAY': 1,
|
| 261 |
+
'HAVE_GETWD': 1,
|
| 262 |
+
'HAVE_GLIBC_MEMMOVE_BUG': 0,
|
| 263 |
+
'HAVE_GRP_H': 1,
|
| 264 |
+
'HAVE_HSTRERROR': 1,
|
| 265 |
+
'HAVE_HTOLE64': 1,
|
| 266 |
+
'HAVE_HYPOT': 1,
|
| 267 |
+
'HAVE_IEEEFP_H': 0,
|
| 268 |
+
'HAVE_IF_NAMEINDEX': 1,
|
| 269 |
+
'HAVE_INET_ATON': 1,
|
| 270 |
+
'HAVE_INET_PTON': 1,
|
| 271 |
+
'HAVE_INITGROUPS': 1,
|
| 272 |
+
'HAVE_INTTYPES_H': 1,
|
| 273 |
+
'HAVE_IO_H': 0,
|
| 274 |
+
'HAVE_IPA_PURE_CONST_BUG': 0,
|
| 275 |
+
'HAVE_KILL': 1,
|
| 276 |
+
'HAVE_KILLPG': 1,
|
| 277 |
+
'HAVE_KQUEUE': 0,
|
| 278 |
+
'HAVE_LANGINFO_H': 1,
|
| 279 |
+
'HAVE_LARGEFILE_SUPPORT': 0,
|
| 280 |
+
'HAVE_LCHFLAGS': 0,
|
| 281 |
+
'HAVE_LCHMOD': 0,
|
| 282 |
+
'HAVE_LCHOWN': 1,
|
| 283 |
+
'HAVE_LGAMMA': 1,
|
| 284 |
+
'HAVE_LIBDL': 1,
|
| 285 |
+
'HAVE_LIBDLD': 0,
|
| 286 |
+
'HAVE_LIBIEEE': 0,
|
| 287 |
+
'HAVE_LIBINTL_H': 1,
|
| 288 |
+
'HAVE_LIBREADLINE': 1,
|
| 289 |
+
'HAVE_LIBRESOLV': 0,
|
| 290 |
+
'HAVE_LIBSENDFILE': 0,
|
| 291 |
+
'HAVE_LIBUTIL_H': 0,
|
| 292 |
+
'HAVE_LINK': 1,
|
| 293 |
+
'HAVE_LINKAT': 1,
|
| 294 |
+
'HAVE_LINUX_CAN_BCM_H': 0,
|
| 295 |
+
'HAVE_LINUX_CAN_H': 1,
|
| 296 |
+
'HAVE_LINUX_CAN_RAW_FD_FRAMES': 0,
|
| 297 |
+
'HAVE_LINUX_CAN_RAW_H': 1,
|
| 298 |
+
'HAVE_LINUX_NETLINK_H': 1,
|
| 299 |
+
'HAVE_LINUX_RANDOM_H': 1,
|
| 300 |
+
'HAVE_LINUX_TIPC_H': 1,
|
| 301 |
+
'HAVE_LOCKF': 1,
|
| 302 |
+
'HAVE_LOG1P': 1,
|
| 303 |
+
'HAVE_LOG2': 1,
|
| 304 |
+
'HAVE_LONG_DOUBLE': 1,
|
| 305 |
+
'HAVE_LSTAT': 1,
|
| 306 |
+
'HAVE_LUTIMES': 1,
|
| 307 |
+
'HAVE_MAKEDEV': 1,
|
| 308 |
+
'HAVE_MBRTOWC': 1,
|
| 309 |
+
'HAVE_MEMMOVE': 1,
|
| 310 |
+
'HAVE_MEMORY_H': 1,
|
| 311 |
+
'HAVE_MEMRCHR': 1,
|
| 312 |
+
'HAVE_MKDIRAT': 1,
|
| 313 |
+
'HAVE_MKFIFO': 1,
|
| 314 |
+
'HAVE_MKFIFOAT': 1,
|
| 315 |
+
'HAVE_MKNOD': 1,
|
| 316 |
+
'HAVE_MKNODAT': 1,
|
| 317 |
+
'HAVE_MKTIME': 1,
|
| 318 |
+
'HAVE_MMAP': 1,
|
| 319 |
+
'HAVE_MREMAP': 1,
|
| 320 |
+
'HAVE_NCURSES_H': 1,
|
| 321 |
+
'HAVE_NDIR_H': 0,
|
| 322 |
+
'HAVE_NETPACKET_PACKET_H': 1,
|
| 323 |
+
'HAVE_NET_IF_H': 1,
|
| 324 |
+
'HAVE_NICE': 1,
|
| 325 |
+
'HAVE_OPENAT': 1,
|
| 326 |
+
'HAVE_OPENPTY': 1,
|
| 327 |
+
'HAVE_PATHCONF': 1,
|
| 328 |
+
'HAVE_PAUSE': 1,
|
| 329 |
+
'HAVE_PIPE2': 1,
|
| 330 |
+
'HAVE_PLOCK': 0,
|
| 331 |
+
'HAVE_POLL': 1,
|
| 332 |
+
'HAVE_POLL_H': 1,
|
| 333 |
+
'HAVE_POSIX_FADVISE': 1,
|
| 334 |
+
'HAVE_POSIX_FALLOCATE': 1,
|
| 335 |
+
'HAVE_PREAD': 1,
|
| 336 |
+
'HAVE_PRLIMIT': 0,
|
| 337 |
+
'HAVE_PROCESS_H': 0,
|
| 338 |
+
'HAVE_PROTOTYPES': 1,
|
| 339 |
+
'HAVE_PTHREAD_ATFORK': 1,
|
| 340 |
+
'HAVE_PTHREAD_DESTRUCTOR': 0,
|
| 341 |
+
'HAVE_PTHREAD_H': 1,
|
| 342 |
+
'HAVE_PTHREAD_INIT': 0,
|
| 343 |
+
'HAVE_PTHREAD_KILL': 1,
|
| 344 |
+
'HAVE_PTHREAD_SIGMASK': 1,
|
| 345 |
+
'HAVE_PTY_H': 1,
|
| 346 |
+
'HAVE_PUTENV': 1,
|
| 347 |
+
'HAVE_PWRITE': 1,
|
| 348 |
+
'HAVE_READLINK': 1,
|
| 349 |
+
'HAVE_READLINKAT': 1,
|
| 350 |
+
'HAVE_READV': 1,
|
| 351 |
+
'HAVE_REALPATH': 1,
|
| 352 |
+
'HAVE_RENAMEAT': 1,
|
| 353 |
+
'HAVE_RL_APPEND_HISTORY': 1,
|
| 354 |
+
'HAVE_RL_CALLBACK': 1,
|
| 355 |
+
'HAVE_RL_CATCH_SIGNAL': 1,
|
| 356 |
+
'HAVE_RL_COMPLETION_APPEND_CHARACTER': 1,
|
| 357 |
+
'HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK': 1,
|
| 358 |
+
'HAVE_RL_COMPLETION_MATCHES': 1,
|
| 359 |
+
'HAVE_RL_COMPLETION_SUPPRESS_APPEND': 1,
|
| 360 |
+
'HAVE_RL_PRE_INPUT_HOOK': 1,
|
| 361 |
+
'HAVE_RL_RESIZE_TERMINAL': 1,
|
| 362 |
+
'HAVE_ROUND': 1,
|
| 363 |
+
'HAVE_SCHED_GET_PRIORITY_MAX': 1,
|
| 364 |
+
'HAVE_SCHED_H': 1,
|
| 365 |
+
'HAVE_SCHED_RR_GET_INTERVAL': 1,
|
| 366 |
+
'HAVE_SCHED_SETAFFINITY': 1,
|
| 367 |
+
'HAVE_SCHED_SETPARAM': 1,
|
| 368 |
+
'HAVE_SCHED_SETSCHEDULER': 1,
|
| 369 |
+
'HAVE_SELECT': 1,
|
| 370 |
+
'HAVE_SEM_GETVALUE': 1,
|
| 371 |
+
'HAVE_SEM_OPEN': 1,
|
| 372 |
+
'HAVE_SEM_TIMEDWAIT': 1,
|
| 373 |
+
'HAVE_SEM_UNLINK': 1,
|
| 374 |
+
'HAVE_SENDFILE': 1,
|
| 375 |
+
'HAVE_SETEGID': 1,
|
| 376 |
+
'HAVE_SETEUID': 1,
|
| 377 |
+
'HAVE_SETGID': 1,
|
| 378 |
+
'HAVE_SETGROUPS': 1,
|
| 379 |
+
'HAVE_SETHOSTNAME': 1,
|
| 380 |
+
'HAVE_SETITIMER': 1,
|
| 381 |
+
'HAVE_SETLOCALE': 1,
|
| 382 |
+
'HAVE_SETPGID': 1,
|
| 383 |
+
'HAVE_SETPGRP': 1,
|
| 384 |
+
'HAVE_SETPRIORITY': 1,
|
| 385 |
+
'HAVE_SETREGID': 1,
|
| 386 |
+
'HAVE_SETRESGID': 1,
|
| 387 |
+
'HAVE_SETRESUID': 1,
|
| 388 |
+
'HAVE_SETREUID': 1,
|
| 389 |
+
'HAVE_SETSID': 1,
|
| 390 |
+
'HAVE_SETUID': 1,
|
| 391 |
+
'HAVE_SETVBUF': 1,
|
| 392 |
+
'HAVE_SHADOW_H': 1,
|
| 393 |
+
'HAVE_SIGACTION': 1,
|
| 394 |
+
'HAVE_SIGALTSTACK': 1,
|
| 395 |
+
'HAVE_SIGINTERRUPT': 1,
|
| 396 |
+
'HAVE_SIGNAL_H': 1,
|
| 397 |
+
'HAVE_SIGPENDING': 1,
|
| 398 |
+
'HAVE_SIGRELSE': 1,
|
| 399 |
+
'HAVE_SIGTIMEDWAIT': 1,
|
| 400 |
+
'HAVE_SIGWAIT': 1,
|
| 401 |
+
'HAVE_SIGWAITINFO': 1,
|
| 402 |
+
'HAVE_SNPRINTF': 1,
|
| 403 |
+
'HAVE_SOCKADDR_ALG': 0,
|
| 404 |
+
'HAVE_SOCKADDR_SA_LEN': 0,
|
| 405 |
+
'HAVE_SOCKADDR_STORAGE': 1,
|
| 406 |
+
'HAVE_SOCKETPAIR': 1,
|
| 407 |
+
'HAVE_SPAWN_H': 1,
|
| 408 |
+
'HAVE_SSIZE_T': 1,
|
| 409 |
+
'HAVE_STATVFS': 1,
|
| 410 |
+
'HAVE_STAT_TV_NSEC': 1,
|
| 411 |
+
'HAVE_STAT_TV_NSEC2': 0,
|
| 412 |
+
'HAVE_STDARG_PROTOTYPES': 1,
|
| 413 |
+
'HAVE_STDINT_H': 1,
|
| 414 |
+
'HAVE_STDLIB_H': 1,
|
| 415 |
+
'HAVE_STD_ATOMIC': 1,
|
| 416 |
+
'HAVE_STRDUP': 1,
|
| 417 |
+
'HAVE_STRFTIME': 1,
|
| 418 |
+
'HAVE_STRINGS_H': 1,
|
| 419 |
+
'HAVE_STRING_H': 1,
|
| 420 |
+
'HAVE_STRLCPY': 0,
|
| 421 |
+
'HAVE_STROPTS_H': 1,
|
| 422 |
+
'HAVE_STRUCT_PASSWD_PW_GECOS': 1,
|
| 423 |
+
'HAVE_STRUCT_PASSWD_PW_PASSWD': 1,
|
| 424 |
+
'HAVE_STRUCT_STAT_ST_BIRTHTIME': 0,
|
| 425 |
+
'HAVE_STRUCT_STAT_ST_BLKSIZE': 1,
|
| 426 |
+
'HAVE_STRUCT_STAT_ST_BLOCKS': 1,
|
| 427 |
+
'HAVE_STRUCT_STAT_ST_FLAGS': 0,
|
| 428 |
+
'HAVE_STRUCT_STAT_ST_GEN': 0,
|
| 429 |
+
'HAVE_STRUCT_STAT_ST_RDEV': 1,
|
| 430 |
+
'HAVE_STRUCT_TM_TM_ZONE': 1,
|
| 431 |
+
'HAVE_SYMLINK': 1,
|
| 432 |
+
'HAVE_SYMLINKAT': 1,
|
| 433 |
+
'HAVE_SYNC': 1,
|
| 434 |
+
'HAVE_SYSCONF': 1,
|
| 435 |
+
'HAVE_SYSEXITS_H': 1,
|
| 436 |
+
'HAVE_SYS_AUDIOIO_H': 0,
|
| 437 |
+
'HAVE_SYS_BSDTTY_H': 0,
|
| 438 |
+
'HAVE_SYS_DEVPOLL_H': 0,
|
| 439 |
+
'HAVE_SYS_DIR_H': 0,
|
| 440 |
+
'HAVE_SYS_ENDIAN_H': 0,
|
| 441 |
+
'HAVE_SYS_EPOLL_H': 1,
|
| 442 |
+
'HAVE_SYS_EVENT_H': 0,
|
| 443 |
+
'HAVE_SYS_FILE_H': 1,
|
| 444 |
+
'HAVE_SYS_IOCTL_H': 1,
|
| 445 |
+
'HAVE_SYS_KERN_CONTROL_H': 0,
|
| 446 |
+
'HAVE_SYS_LOADAVG_H': 0,
|
| 447 |
+
'HAVE_SYS_LOCK_H': 0,
|
| 448 |
+
'HAVE_SYS_MKDEV_H': 0,
|
| 449 |
+
'HAVE_SYS_MODEM_H': 0,
|
| 450 |
+
'HAVE_SYS_NDIR_H': 0,
|
| 451 |
+
'HAVE_SYS_PARAM_H': 1,
|
| 452 |
+
'HAVE_SYS_POLL_H': 1,
|
| 453 |
+
'HAVE_SYS_RANDOM_H': 0,
|
| 454 |
+
'HAVE_SYS_RESOURCE_H': 1,
|
| 455 |
+
'HAVE_SYS_SELECT_H': 1,
|
| 456 |
+
'HAVE_SYS_SENDFILE_H': 1,
|
| 457 |
+
'HAVE_SYS_SOCKET_H': 1,
|
| 458 |
+
'HAVE_SYS_STATVFS_H': 1,
|
| 459 |
+
'HAVE_SYS_STAT_H': 1,
|
| 460 |
+
'HAVE_SYS_SYSCALL_H': 1,
|
| 461 |
+
'HAVE_SYS_SYSMACROS_H': 1,
|
| 462 |
+
'HAVE_SYS_SYS_DOMAIN_H': 0,
|
| 463 |
+
'HAVE_SYS_TERMIO_H': 0,
|
| 464 |
+
'HAVE_SYS_TIMES_H': 1,
|
| 465 |
+
'HAVE_SYS_TIME_H': 1,
|
| 466 |
+
'HAVE_SYS_TYPES_H': 1,
|
| 467 |
+
'HAVE_SYS_UIO_H': 1,
|
| 468 |
+
'HAVE_SYS_UN_H': 1,
|
| 469 |
+
'HAVE_SYS_UTSNAME_H': 1,
|
| 470 |
+
'HAVE_SYS_WAIT_H': 1,
|
| 471 |
+
'HAVE_SYS_XATTR_H': 1,
|
| 472 |
+
'HAVE_TCGETPGRP': 1,
|
| 473 |
+
'HAVE_TCSETPGRP': 1,
|
| 474 |
+
'HAVE_TEMPNAM': 1,
|
| 475 |
+
'HAVE_TERMIOS_H': 1,
|
| 476 |
+
'HAVE_TERM_H': 1,
|
| 477 |
+
'HAVE_TGAMMA': 1,
|
| 478 |
+
'HAVE_TIMEGM': 1,
|
| 479 |
+
'HAVE_TIMES': 1,
|
| 480 |
+
'HAVE_TMPFILE': 1,
|
| 481 |
+
'HAVE_TMPNAM': 1,
|
| 482 |
+
'HAVE_TMPNAM_R': 1,
|
| 483 |
+
'HAVE_TM_ZONE': 1,
|
| 484 |
+
'HAVE_TRUNCATE': 1,
|
| 485 |
+
'HAVE_TZNAME': 0,
|
| 486 |
+
'HAVE_UCS4_TCL': 0,
|
| 487 |
+
'HAVE_UNAME': 1,
|
| 488 |
+
'HAVE_UNISTD_H': 1,
|
| 489 |
+
'HAVE_UNLINKAT': 1,
|
| 490 |
+
'HAVE_UNSETENV': 1,
|
| 491 |
+
'HAVE_USABLE_WCHAR_T': 0,
|
| 492 |
+
'HAVE_UTIL_H': 0,
|
| 493 |
+
'HAVE_UTIMENSAT': 1,
|
| 494 |
+
'HAVE_UTIMES': 1,
|
| 495 |
+
'HAVE_UTIME_H': 1,
|
| 496 |
+
'HAVE_WAIT3': 1,
|
| 497 |
+
'HAVE_WAIT4': 1,
|
| 498 |
+
'HAVE_WAITID': 1,
|
| 499 |
+
'HAVE_WAITPID': 1,
|
| 500 |
+
'HAVE_WCHAR_H': 1,
|
| 501 |
+
'HAVE_WCSCOLL': 1,
|
| 502 |
+
'HAVE_WCSFTIME': 1,
|
| 503 |
+
'HAVE_WCSXFRM': 1,
|
| 504 |
+
'HAVE_WMEMCMP': 1,
|
| 505 |
+
'HAVE_WORKING_TZSET': 1,
|
| 506 |
+
'HAVE_WRITEV': 1,
|
| 507 |
+
'HAVE_ZLIB_COPY': 1,
|
| 508 |
+
'HAVE__GETPTY': 0,
|
| 509 |
+
'HOST_GNU_TYPE': 'x86_64-conda_cos7-linux-gnu',
|
| 510 |
+
'INCLDIRSTOMAKE': '/workspace/anaconda3/include '
|
| 511 |
+
'/workspace/anaconda3/include '
|
| 512 |
+
'/workspace/anaconda3/include/python3.8 '
|
| 513 |
+
'/workspace/anaconda3/include/python3.8',
|
| 514 |
+
'INCLUDEDIR': '/workspace/anaconda3/include',
|
| 515 |
+
'INCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 516 |
+
'INSTALL': '/usr/bin/install -c',
|
| 517 |
+
'INSTALL_DATA': '/usr/bin/install -c -m 644',
|
| 518 |
+
'INSTALL_PROGRAM': '/usr/bin/install -c',
|
| 519 |
+
'INSTALL_SCRIPT': '/usr/bin/install -c',
|
| 520 |
+
'INSTALL_SHARED': '/usr/bin/install -c -m 555',
|
| 521 |
+
'INSTSONAME': 'libpython3.8.a',
|
| 522 |
+
'IO_H': 'Modules/_io/_iomodule.h',
|
| 523 |
+
'IO_OBJS': '\\',
|
| 524 |
+
'LDCXXSHARED': 'x86_64-conda_cos7-linux-gnu-c++ -pthread -shared',
|
| 525 |
+
'LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 526 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 527 |
+
'-L/workspace/anaconda3/lib '
|
| 528 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 529 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 530 |
+
'-L/workspace/anaconda3/lib '
|
| 531 |
+
' ',
|
| 532 |
+
'LDLAST': '',
|
| 533 |
+
'LDLIBRARY': 'libpython3.8.a',
|
| 534 |
+
'LDLIBRARYDIR': '',
|
| 535 |
+
'LDSHARED': 'x86_64-conda_cos7-linux-gnu-gcc -pthread -shared -Wl,-O2 '
|
| 536 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 537 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 538 |
+
'-L/workspace/anaconda3/lib '
|
| 539 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 540 |
+
'-Wl,-z,now '
|
| 541 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 542 |
+
'-L/workspace/anaconda3/lib '
|
| 543 |
+
' ',
|
| 544 |
+
'LDVERSION': '3.8',
|
| 545 |
+
'LIBC': '',
|
| 546 |
+
'LIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 547 |
+
'LIBDIR': '/workspace/anaconda3/lib',
|
| 548 |
+
'LIBFFI_INCLUDEDIR': '/workspace/anaconda3/include',
|
| 549 |
+
'LIBM': '-lm',
|
| 550 |
+
'LIBOBJDIR': 'Python/',
|
| 551 |
+
'LIBOBJS': '',
|
| 552 |
+
'LIBPC': '/workspace/anaconda3/lib/pkgconfig',
|
| 553 |
+
'LIBPL': '/workspace/anaconda3/lib/python3.8/config-3.8-x86_64-linux-gnu',
|
| 554 |
+
'LIBRARY': 'libpython3.8.a',
|
| 555 |
+
'LIBRARY_OBJS': '\\',
|
| 556 |
+
'LIBRARY_OBJS_OMIT_FROZEN': '\\',
|
| 557 |
+
'LIBS': '-lpthread -ldl -lutil -lrt',
|
| 558 |
+
'LIBSUBDIRS': 'tkinter tkinter/test tkinter/test/test_tkinter \\',
|
| 559 |
+
'LINKCC': 'x86_64-conda_cos7-linux-gnu-gcc -pthread',
|
| 560 |
+
'LINKFORSHARED': '-Xlinker -export-dynamic',
|
| 561 |
+
'LIPO_32BIT_FLAGS': '',
|
| 562 |
+
'LLVM_PROF_ERR': 'no',
|
| 563 |
+
'LLVM_PROF_FILE': '',
|
| 564 |
+
'LLVM_PROF_MERGER': 'true',
|
| 565 |
+
'LN': 'ln',
|
| 566 |
+
'LOCALMODLIBS': '',
|
| 567 |
+
'LOG1P_DROPS_ZERO_SIGN': 0,
|
| 568 |
+
'MACHDEP': 'linux',
|
| 569 |
+
'MACHDEPPATH': ':',
|
| 570 |
+
'MACHDEP_OBJS': '',
|
| 571 |
+
'MACHDESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 572 |
+
'MACOSX_DEPLOYMENT_TARGET': '',
|
| 573 |
+
'MAINCC': 'x86_64-conda_cos7-linux-gnu-gcc -pthread',
|
| 574 |
+
'MAJOR_IN_MKDEV': 0,
|
| 575 |
+
'MAJOR_IN_SYSMACROS': 0,
|
| 576 |
+
'MAKESETUP': '/tmp/build/80754af9/python_1510184704423/work/Modules/makesetup',
|
| 577 |
+
'MANDIR': '/workspace/anaconda3/share/man',
|
| 578 |
+
'MKDIR_P': '/bin/mkdir -p',
|
| 579 |
+
'MODLIBS': '',
|
| 580 |
+
'MODNAMES': '_thread posix errno pwd _sre _codecs _weakref _functools '
|
| 581 |
+
'_operator _collections itertools atexit _signal _stat time '
|
| 582 |
+
'_locale _io zipimport faulthandler _tracemalloc _symtable '
|
| 583 |
+
'xxsubtype',
|
| 584 |
+
'MODOBJS': 'Modules/_threadmodule.o Modules/posixmodule.o '
|
| 585 |
+
'Modules/errnomodule.o Modules/pwdmodule.o Modules/_sre.o '
|
| 586 |
+
'Modules/_codecsmodule.o Modules/_weakref.o '
|
| 587 |
+
'Modules/_functoolsmodule.o Modules/_operator.o '
|
| 588 |
+
'Modules/_collectionsmodule.o Modules/itertoolsmodule.o '
|
| 589 |
+
'Modules/atexitmodule.o Modules/signalmodule.o Modules/_stat.o '
|
| 590 |
+
'Modules/timemodule.o Modules/_localemodule.o '
|
| 591 |
+
'Modules/_iomodule.o Modules/iobase.o Modules/fileio.o '
|
| 592 |
+
'Modules/bytesio.o Modules/bufferedio.o Modules/textio.o '
|
| 593 |
+
'Modules/stringio.o Modules/zipimport.o Modules/faulthandler.o '
|
| 594 |
+
'Modules/_tracemalloc.o Modules/hashtable.o '
|
| 595 |
+
'Modules/symtablemodule.o Modules/xxsubtype.o',
|
| 596 |
+
'MODULE_OBJS': '\\',
|
| 597 |
+
'MULTIARCH': 'x86_64-linux-gnu',
|
| 598 |
+
'MULTIARCH_CPPFLAGS': '-DMULTIARCH=\\"x86_64-linux-gnu\\"',
|
| 599 |
+
'MVWDELCH_IS_EXPRESSION': 1,
|
| 600 |
+
'NO_AS_NEEDED': '-Wl,--no-as-needed',
|
| 601 |
+
'OBJECT_OBJS': '\\',
|
| 602 |
+
'OPT': '-DNDEBUG -fwrapv -O2 -Wall -Wstrict-prototypes',
|
| 603 |
+
'OTHER_LIBTOOL_OPT': '',
|
| 604 |
+
'PACKAGE_BUGREPORT': 0,
|
| 605 |
+
'PACKAGE_NAME': 0,
|
| 606 |
+
'PACKAGE_STRING': 0,
|
| 607 |
+
'PACKAGE_TARNAME': 0,
|
| 608 |
+
'PACKAGE_URL': 0,
|
| 609 |
+
'PACKAGE_VERSION': 0,
|
| 610 |
+
'PARSER_HEADERS': '\\',
|
| 611 |
+
'PARSER_OBJS': '\\ Parser/myreadline.o Parser/parsetok.o Parser/tokenizer.o',
|
| 612 |
+
'PGEN': 'Parser/pgen',
|
| 613 |
+
'PGENOBJS': '\\ \\',
|
| 614 |
+
'PGOBJS': '\\',
|
| 615 |
+
'PGO_PROF_GEN_FLAG': '-fprofile-generate',
|
| 616 |
+
'PGO_PROF_USE_FLAG': ' ',
|
| 617 |
+
'PLATDIR': '',
|
| 618 |
+
'POBJS': '\\',
|
| 619 |
+
'POSIX_SEMAPHORES_NOT_ENABLED': 0,
|
| 620 |
+
'PROFILE_TASK': '-m test.regrtest --pgo',
|
| 621 |
+
'PTHREAD_SYSTEM_SCHED_SUPPORTED': 1,
|
| 622 |
+
'PURIFY': '',
|
| 623 |
+
'PY3LIBRARY': '',
|
| 624 |
+
'PYLONG_BITS_IN_DIGIT': 0,
|
| 625 |
+
'PYTHON': 'python',
|
| 626 |
+
'PYTHONFRAMEWORK': '',
|
| 627 |
+
'PYTHONFRAMEWORKDIR': 'no-framework',
|
| 628 |
+
'PYTHONFRAMEWORKINSTALLDIR': '',
|
| 629 |
+
'PYTHONFRAMEWORKPREFIX': '',
|
| 630 |
+
'PYTHONPATH': ':',
|
| 631 |
+
'PYTHON_FOR_BUILD': './python -E',
|
| 632 |
+
'PYTHON_FOR_REGEN': 'python3.8',
|
| 633 |
+
'PYTHON_HEADERS': '\\',
|
| 634 |
+
'PYTHON_OBJS': '\\',
|
| 635 |
+
'PY_BUILD_ENVIRON': '',
|
| 636 |
+
'PY_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall '
|
| 637 |
+
'-Wstrict-prototypes -march=nocona -mtune=haswell '
|
| 638 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 '
|
| 639 |
+
'-pipe '
|
| 640 |
+
' -march=nocona -mtune=haswell '
|
| 641 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 '
|
| 642 |
+
'-pipe '
|
| 643 |
+
' ',
|
| 644 |
+
'PY_CFLAGS_NODIST': '-std=c99 -Wextra -Wno-unused-result '
|
| 645 |
+
'-Wno-unused-parameter -Wno-missing-field-initializers '
|
| 646 |
+
'-march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 647 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 648 |
+
' '
|
| 649 |
+
' '
|
| 650 |
+
' '
|
| 651 |
+
' ',
|
| 652 |
+
'PY_CORE_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 '
|
| 653 |
+
'-Wall -Wstrict-prototypes -march=nocona -mtune=haswell '
|
| 654 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt '
|
| 655 |
+
'-O2 -pipe '
|
| 656 |
+
' -march=nocona -mtune=haswell '
|
| 657 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt '
|
| 658 |
+
'-O2 -pipe '
|
| 659 |
+
' -std=c99 -Wextra '
|
| 660 |
+
'-Wno-unused-result -Wno-unused-parameter '
|
| 661 |
+
'-Wno-missing-field-initializers -march=nocona '
|
| 662 |
+
'-mtune=haswell -ftree-vectorize -fPIC '
|
| 663 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 664 |
+
' '
|
| 665 |
+
' '
|
| 666 |
+
' '
|
| 667 |
+
'-IObjects -IInclude -IPython -I. '
|
| 668 |
+
'-I/tmp/build/80754af9/python_1510184704423/work/Include '
|
| 669 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 670 |
+
'-I/workspace/anaconda3/include '
|
| 671 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 672 |
+
'-I/workspace/anaconda3/include '
|
| 673 |
+
'-DPy_BUILD_CORE',
|
| 674 |
+
'PY_CPPFLAGS': '-IObjects -IInclude -IPython -I. '
|
| 675 |
+
'-I/tmp/build/80754af9/python_1510184704423/work/Include '
|
| 676 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 677 |
+
'-I/workspace/anaconda3/include '
|
| 678 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 679 |
+
'-I/workspace/anaconda3/include',
|
| 680 |
+
'PY_FORMAT_SIZE_T': '"z"',
|
| 681 |
+
'PY_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 682 |
+
'-Wl,-z,now '
|
| 683 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 684 |
+
'-L/workspace/anaconda3/lib '
|
| 685 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 686 |
+
'-Wl,-z,now '
|
| 687 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 688 |
+
'-L/workspace/anaconda3/lib '
|
| 689 |
+
' '
|
| 690 |
+
'',
|
| 691 |
+
'Py_DEBUG': 0,
|
| 692 |
+
'Py_ENABLE_SHARED': 0,
|
| 693 |
+
'Py_HASH_ALGORITHM': 0,
|
| 694 |
+
'QUICKTESTOPTS': '-x test_subprocess test_io test_lib2to3 \\',
|
| 695 |
+
'RANLIB': 'x86_64-conda_cos7-linux-gnu-ranlib',
|
| 696 |
+
'READELF': 'x86_64-conda_cos7-linux-gnu-readelf',
|
| 697 |
+
'RESSRCDIR': 'Mac/Resources/framework',
|
| 698 |
+
'RETSIGTYPE': 'void',
|
| 699 |
+
'RUNSHARED': '',
|
| 700 |
+
'SCRIPTDIR': '/workspace/anaconda3/lib',
|
| 701 |
+
'SETPGRP_HAVE_ARG': 0,
|
| 702 |
+
'SGI_ABI': '',
|
| 703 |
+
'SHELL': '/bin/sh',
|
| 704 |
+
'SHLIBS': '-lpthread -ldl -lutil -lrt',
|
| 705 |
+
'SHLIB_SUFFIX': '.so',
|
| 706 |
+
'SIGNED_RIGHT_SHIFT_ZERO_FILLS': 0,
|
| 707 |
+
'SITEPATH': '',
|
| 708 |
+
'SIZEOF_DOUBLE': 8,
|
| 709 |
+
'SIZEOF_FLOAT': 4,
|
| 710 |
+
'SIZEOF_FPOS_T': 16,
|
| 711 |
+
'SIZEOF_INT': 4,
|
| 712 |
+
'SIZEOF_LONG': 8,
|
| 713 |
+
'SIZEOF_LONG_DOUBLE': 16,
|
| 714 |
+
'SIZEOF_LONG_LONG': 8,
|
| 715 |
+
'SIZEOF_OFF_T': 8,
|
| 716 |
+
'SIZEOF_PID_T': 4,
|
| 717 |
+
'SIZEOF_PTHREAD_T': 8,
|
| 718 |
+
'SIZEOF_SHORT': 2,
|
| 719 |
+
'SIZEOF_SIZE_T': 8,
|
| 720 |
+
'SIZEOF_TIME_T': 8,
|
| 721 |
+
'SIZEOF_UINTPTR_T': 8,
|
| 722 |
+
'SIZEOF_VOID_P': 8,
|
| 723 |
+
'SIZEOF_WCHAR_T': 4,
|
| 724 |
+
'SIZEOF__BOOL': 1,
|
| 725 |
+
'SOABI': 'cpython-38-x86_64-linux-gnu',
|
| 726 |
+
'SRCDIRS': 'Parser Grammar Objects Python Modules Mac Programs',
|
| 727 |
+
'SRC_GDB_HOOKS': '/tmp/build/80754af9/python_1510184704423/work/Tools/gdb/libpython.py',
|
| 728 |
+
'STDC_HEADERS': 1,
|
| 729 |
+
'STRICT_SYSV_CURSES': "/* Don't use ncurses extensions */",
|
| 730 |
+
'STRIPFLAG': '-s',
|
| 731 |
+
'SUBDIRS': '',
|
| 732 |
+
'SUBDIRSTOO': 'Include Lib Misc',
|
| 733 |
+
'SYSLIBS': '-lm',
|
| 734 |
+
'SYS_SELECT_WITH_SYS_TIME': 1,
|
| 735 |
+
'TANH_PRESERVES_ZERO_SIGN': 1,
|
| 736 |
+
'TCLTK_INCLUDES': '-I/workspace/anaconda3/include',
|
| 737 |
+
'TCLTK_LIBS': '-L/workspace/anaconda3/lib '
|
| 738 |
+
'-ltcl8.6 -ltk8.6',
|
| 739 |
+
'TESTOPTS': '',
|
| 740 |
+
'TESTPATH': '',
|
| 741 |
+
'TESTPYTHON': './python',
|
| 742 |
+
'TESTPYTHONOPTS': '',
|
| 743 |
+
'TESTRUNNER': './python '
|
| 744 |
+
'/tmp/build/80754af9/python_1510184704423/work/Tools/scripts/run_tests.py',
|
| 745 |
+
'TESTTIMEOUT': 1200,
|
| 746 |
+
'THREADOBJ': 'Python/thread.o',
|
| 747 |
+
'TIMEMODULE_LIB': 'rt',
|
| 748 |
+
'TIME_WITH_SYS_TIME': 1,
|
| 749 |
+
'TM_IN_SYS_TIME': 0,
|
| 750 |
+
'UNICODE_DEPS': '\\',
|
| 751 |
+
'UNIVERSALSDK': '',
|
| 752 |
+
'USE_COMPUTED_GOTOS': 1,
|
| 753 |
+
'USE_INLINE': 1,
|
| 754 |
+
'VERSION': '3.8',
|
| 755 |
+
'VPATH': '/tmp/build/80754af9/python_1510184704423/work',
|
| 756 |
+
'WANT_SIGFPE_HANDLER': 0,
|
| 757 |
+
'WINDOW_HAS_FLAGS': 1,
|
| 758 |
+
'WITH_DOC_STRINGS': 1,
|
| 759 |
+
'WITH_DTRACE': 0,
|
| 760 |
+
'WITH_DYLD': 0,
|
| 761 |
+
'WITH_LIBINTL': 0,
|
| 762 |
+
'WITH_NEXT_FRAMEWORK': 0,
|
| 763 |
+
'WITH_PYMALLOC': 1,
|
| 764 |
+
'WITH_THREAD': 1,
|
| 765 |
+
'WITH_VALGRIND': 0,
|
| 766 |
+
'X87_DOUBLE_ROUNDING': 0,
|
| 767 |
+
'XMLLIBSUBDIRS': 'xml xml/dom xml/etree xml/parsers xml/sax',
|
| 768 |
+
'abs_builddir': '/tmp/build/80754af9/python_1510184704423/work/build-static',
|
| 769 |
+
'abs_srcdir': '/tmp/build/80754af9/python_1510184704423/work',
|
| 770 |
+
'datarootdir': '/workspace/anaconda3/share',
|
| 771 |
+
'exec_prefix': '/workspace/anaconda3',
|
| 772 |
+
'prefix': '/workspace/anaconda3',
|
| 773 |
+
'srcdir': '/tmp/build/80754af9/python_1510184704423/work'}
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/_sysconfigdata_x86_64_conda_linux_gnu.py
ADDED
|
@@ -0,0 +1,773 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# system configuration generated and used by the sysconfig module
|
| 2 |
+
build_time_vars = {'ABIFLAGS': '',
|
| 3 |
+
'AC_APPLE_UNIVERSAL_BUILD': 0,
|
| 4 |
+
'AIX_GENUINE_CPLUSPLUS': 0,
|
| 5 |
+
'ANDROID_API_LEVEL': 0,
|
| 6 |
+
'AR': 'x86_64-conda-linux-gnu-ar',
|
| 7 |
+
'ARFLAGS': 'rc',
|
| 8 |
+
'BASECFLAGS': '-Wno-unused-result -Wsign-compare',
|
| 9 |
+
'BASECPPFLAGS': '-IObjects -IInclude -IPython',
|
| 10 |
+
'BASEMODLIBS': '',
|
| 11 |
+
'BINDIR': '/workspace/anaconda3/bin',
|
| 12 |
+
'BINLIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 13 |
+
'BLDLIBRARY': 'libpython3.8.a',
|
| 14 |
+
'BLDSHARED': 'x86_64-conda-linux-gnu-gcc -pthread -shared -Wl,-O2 '
|
| 15 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 16 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 17 |
+
'-L/workspace/anaconda3/lib '
|
| 18 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 19 |
+
'-Wl,-z,now '
|
| 20 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 21 |
+
'-L/workspace/anaconda3/lib '
|
| 22 |
+
' '
|
| 23 |
+
'',
|
| 24 |
+
'BUILDEXE': '',
|
| 25 |
+
'BUILDPYTHON': 'python',
|
| 26 |
+
'BUILD_GNU_TYPE': 'x86_64-conda-linux-gnu',
|
| 27 |
+
'BYTESTR_DEPS': '\\',
|
| 28 |
+
'CC': 'x86_64-conda-linux-gnu-gcc -pthread',
|
| 29 |
+
'CCSHARED': '-fPIC',
|
| 30 |
+
'CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall '
|
| 31 |
+
'-Wstrict-prototypes -march=nocona -mtune=haswell -ftree-vectorize '
|
| 32 |
+
'-fPIC -fstack-protector-strong -fno-plt -O2 -pipe '
|
| 33 |
+
' '
|
| 34 |
+
'-march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 35 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 36 |
+
' ',
|
| 37 |
+
'CFLAGSFORSHARED': '',
|
| 38 |
+
'CFLAGS_ALIASING': '',
|
| 39 |
+
'CONFIGFILES': 'configure configure.ac acconfig.h pyconfig.h.in '
|
| 40 |
+
'Makefile.pre.in',
|
| 41 |
+
'CONFIGURE_CFLAGS': '-march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 42 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 43 |
+
' '
|
| 44 |
+
' ',
|
| 45 |
+
'CONFIGURE_CFLAGS_NODIST': '-std=c99 -Wextra -Wno-unused-result '
|
| 46 |
+
'-Wno-unused-parameter '
|
| 47 |
+
'-Wno-missing-field-initializers',
|
| 48 |
+
'CONFIGURE_CPPFLAGS': '-D_FORTIFY_SOURCE=2 -O2 '
|
| 49 |
+
'-I/workspace/anaconda3/include',
|
| 50 |
+
'CONFIGURE_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 51 |
+
'-Wl,-z,now '
|
| 52 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 53 |
+
'-L/workspace/anaconda3/lib',
|
| 54 |
+
'CONFIG_ARGS': "'--prefix=/workspace/anaconda3' "
|
| 55 |
+
"'--build=x86_64-conda-linux-gnu' "
|
| 56 |
+
"'--host=x86_64-conda-linux-gnu' '--enable-ipv6' "
|
| 57 |
+
"'--with-ensurepip=no' '--with-computed-gotos' "
|
| 58 |
+
"'--with-system-ffi' '--enable-loadable-sqlite-extensions' "
|
| 59 |
+
"'--with-tcltk-includes=-I/workspace/anaconda3/include' "
|
| 60 |
+
"'--with-tcltk-libs=-L/workspace/anaconda3/lib "
|
| 61 |
+
"-ltcl8.6 -ltk8.6' '--enable-optimizations' '--with-lto' "
|
| 62 |
+
"'--disable-shared' 'build_alias=x86_64-conda-linux-gnu' "
|
| 63 |
+
"'host_alias=x86_64-conda-linux-gnu' "
|
| 64 |
+
"'CC=x86_64-conda-linux-gnu-gcc' 'CFLAGS=-march=nocona "
|
| 65 |
+
'-mtune=haswell -ftree-vectorize -fPIC '
|
| 66 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 67 |
+
' '
|
| 68 |
+
"' 'LDFLAGS=-Wl,-O2 -Wl,--sort-common -Wl,--as-needed "
|
| 69 |
+
'-Wl,-z,relro -Wl,-z,now '
|
| 70 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 71 |
+
"-L/workspace/anaconda3/lib' "
|
| 72 |
+
"'CPPFLAGS=-D_FORTIFY_SOURCE=2 -O2 "
|
| 73 |
+
"-I/workspace/anaconda3/include' "
|
| 74 |
+
"'CPP=/workspace/anaconda3/bin/x86_64-conda-linux-gnu-cpp' "
|
| 75 |
+
"'PKG_CONFIG_PATH=/workspace/anaconda3/lib/pkgconfig'",
|
| 76 |
+
'CONFINCLUDEDIR': '/workspace/anaconda3/include',
|
| 77 |
+
'CONFINCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 78 |
+
'COREPYTHONPATH': ':',
|
| 79 |
+
'COVERAGE_INFO': '/tmp/build/80754af9/python_1510184704423/work/build-static/coverage.info',
|
| 80 |
+
'COVERAGE_REPORT': '/tmp/build/80754af9/python_1510184704423/work/build-static/lcov-report',
|
| 81 |
+
'COVERAGE_REPORT_OPTIONS': '--no-branch-coverage --title "CPython lcov '
|
| 82 |
+
'report"',
|
| 83 |
+
'CPPFLAGS': '-IObjects -IInclude -IPython -I. '
|
| 84 |
+
'-I/tmp/build/80754af9/python_1510184704423/work/Include '
|
| 85 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 86 |
+
'-I/workspace/anaconda3/include '
|
| 87 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 88 |
+
'-I/workspace/anaconda3/include',
|
| 89 |
+
'CXX': 'x86_64-conda-linux-gnu-c++ -pthread',
|
| 90 |
+
'DESTDIRS': '/workspace/anaconda3 '
|
| 91 |
+
'/workspace/anaconda3/lib '
|
| 92 |
+
'/workspace/anaconda3/lib/python3.8 '
|
| 93 |
+
'/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 94 |
+
'DESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 95 |
+
'DESTPATH': '',
|
| 96 |
+
'DESTSHARED': '/workspace/anaconda3/lib/python3.8/lib-dynload',
|
| 97 |
+
'DFLAGS': '',
|
| 98 |
+
'DIRMODE': 755,
|
| 99 |
+
'DIST': 'README ChangeLog configure configure.ac acconfig.h pyconfig.h.in '
|
| 100 |
+
'Makefile.pre.in Include Lib Misc Ext-dummy',
|
| 101 |
+
'DISTDIRS': 'Include Lib Misc Ext-dummy',
|
| 102 |
+
'DISTFILES': 'README ChangeLog configure configure.ac acconfig.h '
|
| 103 |
+
'pyconfig.h.in Makefile.pre.in',
|
| 104 |
+
'DLINCLDIR': '.',
|
| 105 |
+
'DLLLIBRARY': '',
|
| 106 |
+
'DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754': 0,
|
| 107 |
+
'DOUBLE_IS_BIG_ENDIAN_IEEE754': 0,
|
| 108 |
+
'DOUBLE_IS_LITTLE_ENDIAN_IEEE754': 1,
|
| 109 |
+
'DTRACE': '',
|
| 110 |
+
'DTRACE_DEPS': '\\',
|
| 111 |
+
'DTRACE_HEADERS': '',
|
| 112 |
+
'DTRACE_OBJS': '',
|
| 113 |
+
'DYNLOADFILE': 'dynload_shlib.o',
|
| 114 |
+
'ENABLE_IPV6': 1,
|
| 115 |
+
'ENSUREPIP': 'no',
|
| 116 |
+
'EXE': '',
|
| 117 |
+
'EXEMODE': 755,
|
| 118 |
+
'EXTRAMACHDEPPATH': '',
|
| 119 |
+
'EXTRATESTOPTS': '',
|
| 120 |
+
'EXT_SUFFIX': '.cpython-38-x86_64-linux-gnu.so',
|
| 121 |
+
'FILEMODE': 644,
|
| 122 |
+
'FLOCK_NEEDS_LIBBSD': 0,
|
| 123 |
+
'GETPGRP_HAVE_ARG': 0,
|
| 124 |
+
'GETTIMEOFDAY_NO_TZ': 0,
|
| 125 |
+
'GITBRANCH': '',
|
| 126 |
+
'GITTAG': '',
|
| 127 |
+
'GITVERSION': '',
|
| 128 |
+
'GNULD': 'yes',
|
| 129 |
+
'HAVE_ACCEPT4': 1,
|
| 130 |
+
'HAVE_ACOSH': 1,
|
| 131 |
+
'HAVE_ADDRINFO': 1,
|
| 132 |
+
'HAVE_ALARM': 1,
|
| 133 |
+
'HAVE_ALIGNED_REQUIRED': 0,
|
| 134 |
+
'HAVE_ALLOCA_H': 1,
|
| 135 |
+
'HAVE_ALTZONE': 0,
|
| 136 |
+
'HAVE_ASINH': 1,
|
| 137 |
+
'HAVE_ASM_TYPES_H': 1,
|
| 138 |
+
'HAVE_ATANH': 1,
|
| 139 |
+
'HAVE_BIND_TEXTDOMAIN_CODESET': 1,
|
| 140 |
+
'HAVE_BLUETOOTH_BLUETOOTH_H': 0,
|
| 141 |
+
'HAVE_BLUETOOTH_H': 0,
|
| 142 |
+
'HAVE_BROKEN_MBSTOWCS': 0,
|
| 143 |
+
'HAVE_BROKEN_NICE': 0,
|
| 144 |
+
'HAVE_BROKEN_PIPE_BUF': 0,
|
| 145 |
+
'HAVE_BROKEN_POLL': 0,
|
| 146 |
+
'HAVE_BROKEN_POSIX_SEMAPHORES': 0,
|
| 147 |
+
'HAVE_BROKEN_PTHREAD_SIGMASK': 0,
|
| 148 |
+
'HAVE_BROKEN_SEM_GETVALUE': 0,
|
| 149 |
+
'HAVE_BROKEN_UNSETENV': 0,
|
| 150 |
+
'HAVE_BUILTIN_ATOMIC': 1,
|
| 151 |
+
'HAVE_CHFLAGS': 0,
|
| 152 |
+
'HAVE_CHOWN': 1,
|
| 153 |
+
'HAVE_CHROOT': 1,
|
| 154 |
+
'HAVE_CLOCK': 1,
|
| 155 |
+
'HAVE_CLOCK_GETRES': 1,
|
| 156 |
+
'HAVE_CLOCK_GETTIME': 1,
|
| 157 |
+
'HAVE_CLOCK_SETTIME': 1,
|
| 158 |
+
'HAVE_COMPUTED_GOTOS': 1,
|
| 159 |
+
'HAVE_CONFSTR': 1,
|
| 160 |
+
'HAVE_CONIO_H': 0,
|
| 161 |
+
'HAVE_COPYSIGN': 1,
|
| 162 |
+
'HAVE_CTERMID': 1,
|
| 163 |
+
'HAVE_CTERMID_R': 0,
|
| 164 |
+
'HAVE_CURSES_H': 1,
|
| 165 |
+
'HAVE_CURSES_IS_TERM_RESIZED': 1,
|
| 166 |
+
'HAVE_CURSES_RESIZETERM': 1,
|
| 167 |
+
'HAVE_CURSES_RESIZE_TERM': 1,
|
| 168 |
+
'HAVE_DECL_ISFINITE': 1,
|
| 169 |
+
'HAVE_DECL_ISINF': 1,
|
| 170 |
+
'HAVE_DECL_ISNAN': 1,
|
| 171 |
+
'HAVE_DECL_RTLD_DEEPBIND': 1,
|
| 172 |
+
'HAVE_DECL_RTLD_GLOBAL': 1,
|
| 173 |
+
'HAVE_DECL_RTLD_LAZY': 1,
|
| 174 |
+
'HAVE_DECL_RTLD_LOCAL': 1,
|
| 175 |
+
'HAVE_DECL_RTLD_NODELETE': 1,
|
| 176 |
+
'HAVE_DECL_RTLD_NOLOAD': 1,
|
| 177 |
+
'HAVE_DECL_RTLD_NOW': 1,
|
| 178 |
+
'HAVE_DECL_TZNAME': 0,
|
| 179 |
+
'HAVE_DEVICE_MACROS': 1,
|
| 180 |
+
'HAVE_DEV_PTC': 0,
|
| 181 |
+
'HAVE_DEV_PTMX': 1,
|
| 182 |
+
'HAVE_DIRECT_H': 0,
|
| 183 |
+
'HAVE_DIRENT_D_TYPE': 1,
|
| 184 |
+
'HAVE_DIRENT_H': 1,
|
| 185 |
+
'HAVE_DIRFD': 1,
|
| 186 |
+
'HAVE_DLFCN_H': 1,
|
| 187 |
+
'HAVE_DLOPEN': 1,
|
| 188 |
+
'HAVE_DUP2': 1,
|
| 189 |
+
'HAVE_DUP3': 1,
|
| 190 |
+
'HAVE_DYNAMIC_LOADING': 1,
|
| 191 |
+
'HAVE_ENDIAN_H': 1,
|
| 192 |
+
'HAVE_EPOLL': 1,
|
| 193 |
+
'HAVE_EPOLL_CREATE1': 1,
|
| 194 |
+
'HAVE_ERF': 1,
|
| 195 |
+
'HAVE_ERFC': 1,
|
| 196 |
+
'HAVE_ERRNO_H': 1,
|
| 197 |
+
'HAVE_EXECV': 1,
|
| 198 |
+
'HAVE_EXPM1': 1,
|
| 199 |
+
'HAVE_FACCESSAT': 1,
|
| 200 |
+
'HAVE_FCHDIR': 1,
|
| 201 |
+
'HAVE_FCHMOD': 1,
|
| 202 |
+
'HAVE_FCHMODAT': 1,
|
| 203 |
+
'HAVE_FCHOWN': 1,
|
| 204 |
+
'HAVE_FCHOWNAT': 1,
|
| 205 |
+
'HAVE_FCNTL_H': 1,
|
| 206 |
+
'HAVE_FDATASYNC': 1,
|
| 207 |
+
'HAVE_FDOPENDIR': 1,
|
| 208 |
+
'HAVE_FEXECVE': 1,
|
| 209 |
+
'HAVE_FINITE': 1,
|
| 210 |
+
'HAVE_FLOCK': 1,
|
| 211 |
+
'HAVE_FORK': 1,
|
| 212 |
+
'HAVE_FORKPTY': 1,
|
| 213 |
+
'HAVE_FPATHCONF': 1,
|
| 214 |
+
'HAVE_FSEEK64': 0,
|
| 215 |
+
'HAVE_FSEEKO': 1,
|
| 216 |
+
'HAVE_FSTATAT': 1,
|
| 217 |
+
'HAVE_FSTATVFS': 1,
|
| 218 |
+
'HAVE_FSYNC': 1,
|
| 219 |
+
'HAVE_FTELL64': 0,
|
| 220 |
+
'HAVE_FTELLO': 1,
|
| 221 |
+
'HAVE_FTIME': 1,
|
| 222 |
+
'HAVE_FTRUNCATE': 1,
|
| 223 |
+
'HAVE_FUTIMENS': 1,
|
| 224 |
+
'HAVE_FUTIMES': 1,
|
| 225 |
+
'HAVE_FUTIMESAT': 1,
|
| 226 |
+
'HAVE_GAI_STRERROR': 1,
|
| 227 |
+
'HAVE_GAMMA': 1,
|
| 228 |
+
'HAVE_GCC_ASM_FOR_MC68881': 0,
|
| 229 |
+
'HAVE_GCC_ASM_FOR_X64': 1,
|
| 230 |
+
'HAVE_GCC_ASM_FOR_X87': 1,
|
| 231 |
+
'HAVE_GCC_UINT128_T': 1,
|
| 232 |
+
'HAVE_GETADDRINFO': 1,
|
| 233 |
+
'HAVE_GETC_UNLOCKED': 1,
|
| 234 |
+
'HAVE_GETENTROPY': 0,
|
| 235 |
+
'HAVE_GETGROUPLIST': 1,
|
| 236 |
+
'HAVE_GETGROUPS': 1,
|
| 237 |
+
'HAVE_GETHOSTBYNAME': 0,
|
| 238 |
+
'HAVE_GETHOSTBYNAME_R': 1,
|
| 239 |
+
'HAVE_GETHOSTBYNAME_R_3_ARG': 0,
|
| 240 |
+
'HAVE_GETHOSTBYNAME_R_5_ARG': 0,
|
| 241 |
+
'HAVE_GETHOSTBYNAME_R_6_ARG': 1,
|
| 242 |
+
'HAVE_GETITIMER': 1,
|
| 243 |
+
'HAVE_GETLOADAVG': 1,
|
| 244 |
+
'HAVE_GETLOGIN': 1,
|
| 245 |
+
'HAVE_GETNAMEINFO': 1,
|
| 246 |
+
'HAVE_GETPAGESIZE': 1,
|
| 247 |
+
'HAVE_GETPEERNAME': 1,
|
| 248 |
+
'HAVE_GETPGID': 1,
|
| 249 |
+
'HAVE_GETPGRP': 1,
|
| 250 |
+
'HAVE_GETPID': 1,
|
| 251 |
+
'HAVE_GETPRIORITY': 1,
|
| 252 |
+
'HAVE_GETPWENT': 1,
|
| 253 |
+
'HAVE_GETRANDOM': 0,
|
| 254 |
+
'HAVE_GETRANDOM_SYSCALL': 0,
|
| 255 |
+
'HAVE_GETRESGID': 1,
|
| 256 |
+
'HAVE_GETRESUID': 1,
|
| 257 |
+
'HAVE_GETSID': 1,
|
| 258 |
+
'HAVE_GETSPENT': 1,
|
| 259 |
+
'HAVE_GETSPNAM': 1,
|
| 260 |
+
'HAVE_GETTIMEOFDAY': 1,
|
| 261 |
+
'HAVE_GETWD': 1,
|
| 262 |
+
'HAVE_GLIBC_MEMMOVE_BUG': 0,
|
| 263 |
+
'HAVE_GRP_H': 1,
|
| 264 |
+
'HAVE_HSTRERROR': 1,
|
| 265 |
+
'HAVE_HTOLE64': 1,
|
| 266 |
+
'HAVE_HYPOT': 1,
|
| 267 |
+
'HAVE_IEEEFP_H': 0,
|
| 268 |
+
'HAVE_IF_NAMEINDEX': 1,
|
| 269 |
+
'HAVE_INET_ATON': 1,
|
| 270 |
+
'HAVE_INET_PTON': 1,
|
| 271 |
+
'HAVE_INITGROUPS': 1,
|
| 272 |
+
'HAVE_INTTYPES_H': 1,
|
| 273 |
+
'HAVE_IO_H': 0,
|
| 274 |
+
'HAVE_IPA_PURE_CONST_BUG': 0,
|
| 275 |
+
'HAVE_KILL': 1,
|
| 276 |
+
'HAVE_KILLPG': 1,
|
| 277 |
+
'HAVE_KQUEUE': 0,
|
| 278 |
+
'HAVE_LANGINFO_H': 1,
|
| 279 |
+
'HAVE_LARGEFILE_SUPPORT': 0,
|
| 280 |
+
'HAVE_LCHFLAGS': 0,
|
| 281 |
+
'HAVE_LCHMOD': 0,
|
| 282 |
+
'HAVE_LCHOWN': 1,
|
| 283 |
+
'HAVE_LGAMMA': 1,
|
| 284 |
+
'HAVE_LIBDL': 1,
|
| 285 |
+
'HAVE_LIBDLD': 0,
|
| 286 |
+
'HAVE_LIBIEEE': 0,
|
| 287 |
+
'HAVE_LIBINTL_H': 1,
|
| 288 |
+
'HAVE_LIBREADLINE': 1,
|
| 289 |
+
'HAVE_LIBRESOLV': 0,
|
| 290 |
+
'HAVE_LIBSENDFILE': 0,
|
| 291 |
+
'HAVE_LIBUTIL_H': 0,
|
| 292 |
+
'HAVE_LINK': 1,
|
| 293 |
+
'HAVE_LINKAT': 1,
|
| 294 |
+
'HAVE_LINUX_CAN_BCM_H': 0,
|
| 295 |
+
'HAVE_LINUX_CAN_H': 1,
|
| 296 |
+
'HAVE_LINUX_CAN_RAW_FD_FRAMES': 0,
|
| 297 |
+
'HAVE_LINUX_CAN_RAW_H': 1,
|
| 298 |
+
'HAVE_LINUX_NETLINK_H': 1,
|
| 299 |
+
'HAVE_LINUX_RANDOM_H': 1,
|
| 300 |
+
'HAVE_LINUX_TIPC_H': 1,
|
| 301 |
+
'HAVE_LOCKF': 1,
|
| 302 |
+
'HAVE_LOG1P': 1,
|
| 303 |
+
'HAVE_LOG2': 1,
|
| 304 |
+
'HAVE_LONG_DOUBLE': 1,
|
| 305 |
+
'HAVE_LSTAT': 1,
|
| 306 |
+
'HAVE_LUTIMES': 1,
|
| 307 |
+
'HAVE_MAKEDEV': 1,
|
| 308 |
+
'HAVE_MBRTOWC': 1,
|
| 309 |
+
'HAVE_MEMMOVE': 1,
|
| 310 |
+
'HAVE_MEMORY_H': 1,
|
| 311 |
+
'HAVE_MEMRCHR': 1,
|
| 312 |
+
'HAVE_MKDIRAT': 1,
|
| 313 |
+
'HAVE_MKFIFO': 1,
|
| 314 |
+
'HAVE_MKFIFOAT': 1,
|
| 315 |
+
'HAVE_MKNOD': 1,
|
| 316 |
+
'HAVE_MKNODAT': 1,
|
| 317 |
+
'HAVE_MKTIME': 1,
|
| 318 |
+
'HAVE_MMAP': 1,
|
| 319 |
+
'HAVE_MREMAP': 1,
|
| 320 |
+
'HAVE_NCURSES_H': 1,
|
| 321 |
+
'HAVE_NDIR_H': 0,
|
| 322 |
+
'HAVE_NETPACKET_PACKET_H': 1,
|
| 323 |
+
'HAVE_NET_IF_H': 1,
|
| 324 |
+
'HAVE_NICE': 1,
|
| 325 |
+
'HAVE_OPENAT': 1,
|
| 326 |
+
'HAVE_OPENPTY': 1,
|
| 327 |
+
'HAVE_PATHCONF': 1,
|
| 328 |
+
'HAVE_PAUSE': 1,
|
| 329 |
+
'HAVE_PIPE2': 1,
|
| 330 |
+
'HAVE_PLOCK': 0,
|
| 331 |
+
'HAVE_POLL': 1,
|
| 332 |
+
'HAVE_POLL_H': 1,
|
| 333 |
+
'HAVE_POSIX_FADVISE': 1,
|
| 334 |
+
'HAVE_POSIX_FALLOCATE': 1,
|
| 335 |
+
'HAVE_PREAD': 1,
|
| 336 |
+
'HAVE_PRLIMIT': 0,
|
| 337 |
+
'HAVE_PROCESS_H': 0,
|
| 338 |
+
'HAVE_PROTOTYPES': 1,
|
| 339 |
+
'HAVE_PTHREAD_ATFORK': 1,
|
| 340 |
+
'HAVE_PTHREAD_DESTRUCTOR': 0,
|
| 341 |
+
'HAVE_PTHREAD_H': 1,
|
| 342 |
+
'HAVE_PTHREAD_INIT': 0,
|
| 343 |
+
'HAVE_PTHREAD_KILL': 1,
|
| 344 |
+
'HAVE_PTHREAD_SIGMASK': 1,
|
| 345 |
+
'HAVE_PTY_H': 1,
|
| 346 |
+
'HAVE_PUTENV': 1,
|
| 347 |
+
'HAVE_PWRITE': 1,
|
| 348 |
+
'HAVE_READLINK': 1,
|
| 349 |
+
'HAVE_READLINKAT': 1,
|
| 350 |
+
'HAVE_READV': 1,
|
| 351 |
+
'HAVE_REALPATH': 1,
|
| 352 |
+
'HAVE_RENAMEAT': 1,
|
| 353 |
+
'HAVE_RL_APPEND_HISTORY': 1,
|
| 354 |
+
'HAVE_RL_CALLBACK': 1,
|
| 355 |
+
'HAVE_RL_CATCH_SIGNAL': 1,
|
| 356 |
+
'HAVE_RL_COMPLETION_APPEND_CHARACTER': 1,
|
| 357 |
+
'HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK': 1,
|
| 358 |
+
'HAVE_RL_COMPLETION_MATCHES': 1,
|
| 359 |
+
'HAVE_RL_COMPLETION_SUPPRESS_APPEND': 1,
|
| 360 |
+
'HAVE_RL_PRE_INPUT_HOOK': 1,
|
| 361 |
+
'HAVE_RL_RESIZE_TERMINAL': 1,
|
| 362 |
+
'HAVE_ROUND': 1,
|
| 363 |
+
'HAVE_SCHED_GET_PRIORITY_MAX': 1,
|
| 364 |
+
'HAVE_SCHED_H': 1,
|
| 365 |
+
'HAVE_SCHED_RR_GET_INTERVAL': 1,
|
| 366 |
+
'HAVE_SCHED_SETAFFINITY': 1,
|
| 367 |
+
'HAVE_SCHED_SETPARAM': 1,
|
| 368 |
+
'HAVE_SCHED_SETSCHEDULER': 1,
|
| 369 |
+
'HAVE_SELECT': 1,
|
| 370 |
+
'HAVE_SEM_GETVALUE': 1,
|
| 371 |
+
'HAVE_SEM_OPEN': 1,
|
| 372 |
+
'HAVE_SEM_TIMEDWAIT': 1,
|
| 373 |
+
'HAVE_SEM_UNLINK': 1,
|
| 374 |
+
'HAVE_SENDFILE': 1,
|
| 375 |
+
'HAVE_SETEGID': 1,
|
| 376 |
+
'HAVE_SETEUID': 1,
|
| 377 |
+
'HAVE_SETGID': 1,
|
| 378 |
+
'HAVE_SETGROUPS': 1,
|
| 379 |
+
'HAVE_SETHOSTNAME': 1,
|
| 380 |
+
'HAVE_SETITIMER': 1,
|
| 381 |
+
'HAVE_SETLOCALE': 1,
|
| 382 |
+
'HAVE_SETPGID': 1,
|
| 383 |
+
'HAVE_SETPGRP': 1,
|
| 384 |
+
'HAVE_SETPRIORITY': 1,
|
| 385 |
+
'HAVE_SETREGID': 1,
|
| 386 |
+
'HAVE_SETRESGID': 1,
|
| 387 |
+
'HAVE_SETRESUID': 1,
|
| 388 |
+
'HAVE_SETREUID': 1,
|
| 389 |
+
'HAVE_SETSID': 1,
|
| 390 |
+
'HAVE_SETUID': 1,
|
| 391 |
+
'HAVE_SETVBUF': 1,
|
| 392 |
+
'HAVE_SHADOW_H': 1,
|
| 393 |
+
'HAVE_SIGACTION': 1,
|
| 394 |
+
'HAVE_SIGALTSTACK': 1,
|
| 395 |
+
'HAVE_SIGINTERRUPT': 1,
|
| 396 |
+
'HAVE_SIGNAL_H': 1,
|
| 397 |
+
'HAVE_SIGPENDING': 1,
|
| 398 |
+
'HAVE_SIGRELSE': 1,
|
| 399 |
+
'HAVE_SIGTIMEDWAIT': 1,
|
| 400 |
+
'HAVE_SIGWAIT': 1,
|
| 401 |
+
'HAVE_SIGWAITINFO': 1,
|
| 402 |
+
'HAVE_SNPRINTF': 1,
|
| 403 |
+
'HAVE_SOCKADDR_ALG': 0,
|
| 404 |
+
'HAVE_SOCKADDR_SA_LEN': 0,
|
| 405 |
+
'HAVE_SOCKADDR_STORAGE': 1,
|
| 406 |
+
'HAVE_SOCKETPAIR': 1,
|
| 407 |
+
'HAVE_SPAWN_H': 1,
|
| 408 |
+
'HAVE_SSIZE_T': 1,
|
| 409 |
+
'HAVE_STATVFS': 1,
|
| 410 |
+
'HAVE_STAT_TV_NSEC': 1,
|
| 411 |
+
'HAVE_STAT_TV_NSEC2': 0,
|
| 412 |
+
'HAVE_STDARG_PROTOTYPES': 1,
|
| 413 |
+
'HAVE_STDINT_H': 1,
|
| 414 |
+
'HAVE_STDLIB_H': 1,
|
| 415 |
+
'HAVE_STD_ATOMIC': 1,
|
| 416 |
+
'HAVE_STRDUP': 1,
|
| 417 |
+
'HAVE_STRFTIME': 1,
|
| 418 |
+
'HAVE_STRINGS_H': 1,
|
| 419 |
+
'HAVE_STRING_H': 1,
|
| 420 |
+
'HAVE_STRLCPY': 0,
|
| 421 |
+
'HAVE_STROPTS_H': 1,
|
| 422 |
+
'HAVE_STRUCT_PASSWD_PW_GECOS': 1,
|
| 423 |
+
'HAVE_STRUCT_PASSWD_PW_PASSWD': 1,
|
| 424 |
+
'HAVE_STRUCT_STAT_ST_BIRTHTIME': 0,
|
| 425 |
+
'HAVE_STRUCT_STAT_ST_BLKSIZE': 1,
|
| 426 |
+
'HAVE_STRUCT_STAT_ST_BLOCKS': 1,
|
| 427 |
+
'HAVE_STRUCT_STAT_ST_FLAGS': 0,
|
| 428 |
+
'HAVE_STRUCT_STAT_ST_GEN': 0,
|
| 429 |
+
'HAVE_STRUCT_STAT_ST_RDEV': 1,
|
| 430 |
+
'HAVE_STRUCT_TM_TM_ZONE': 1,
|
| 431 |
+
'HAVE_SYMLINK': 1,
|
| 432 |
+
'HAVE_SYMLINKAT': 1,
|
| 433 |
+
'HAVE_SYNC': 1,
|
| 434 |
+
'HAVE_SYSCONF': 1,
|
| 435 |
+
'HAVE_SYSEXITS_H': 1,
|
| 436 |
+
'HAVE_SYS_AUDIOIO_H': 0,
|
| 437 |
+
'HAVE_SYS_BSDTTY_H': 0,
|
| 438 |
+
'HAVE_SYS_DEVPOLL_H': 0,
|
| 439 |
+
'HAVE_SYS_DIR_H': 0,
|
| 440 |
+
'HAVE_SYS_ENDIAN_H': 0,
|
| 441 |
+
'HAVE_SYS_EPOLL_H': 1,
|
| 442 |
+
'HAVE_SYS_EVENT_H': 0,
|
| 443 |
+
'HAVE_SYS_FILE_H': 1,
|
| 444 |
+
'HAVE_SYS_IOCTL_H': 1,
|
| 445 |
+
'HAVE_SYS_KERN_CONTROL_H': 0,
|
| 446 |
+
'HAVE_SYS_LOADAVG_H': 0,
|
| 447 |
+
'HAVE_SYS_LOCK_H': 0,
|
| 448 |
+
'HAVE_SYS_MKDEV_H': 0,
|
| 449 |
+
'HAVE_SYS_MODEM_H': 0,
|
| 450 |
+
'HAVE_SYS_NDIR_H': 0,
|
| 451 |
+
'HAVE_SYS_PARAM_H': 1,
|
| 452 |
+
'HAVE_SYS_POLL_H': 1,
|
| 453 |
+
'HAVE_SYS_RANDOM_H': 0,
|
| 454 |
+
'HAVE_SYS_RESOURCE_H': 1,
|
| 455 |
+
'HAVE_SYS_SELECT_H': 1,
|
| 456 |
+
'HAVE_SYS_SENDFILE_H': 1,
|
| 457 |
+
'HAVE_SYS_SOCKET_H': 1,
|
| 458 |
+
'HAVE_SYS_STATVFS_H': 1,
|
| 459 |
+
'HAVE_SYS_STAT_H': 1,
|
| 460 |
+
'HAVE_SYS_SYSCALL_H': 1,
|
| 461 |
+
'HAVE_SYS_SYSMACROS_H': 1,
|
| 462 |
+
'HAVE_SYS_SYS_DOMAIN_H': 0,
|
| 463 |
+
'HAVE_SYS_TERMIO_H': 0,
|
| 464 |
+
'HAVE_SYS_TIMES_H': 1,
|
| 465 |
+
'HAVE_SYS_TIME_H': 1,
|
| 466 |
+
'HAVE_SYS_TYPES_H': 1,
|
| 467 |
+
'HAVE_SYS_UIO_H': 1,
|
| 468 |
+
'HAVE_SYS_UN_H': 1,
|
| 469 |
+
'HAVE_SYS_UTSNAME_H': 1,
|
| 470 |
+
'HAVE_SYS_WAIT_H': 1,
|
| 471 |
+
'HAVE_SYS_XATTR_H': 1,
|
| 472 |
+
'HAVE_TCGETPGRP': 1,
|
| 473 |
+
'HAVE_TCSETPGRP': 1,
|
| 474 |
+
'HAVE_TEMPNAM': 1,
|
| 475 |
+
'HAVE_TERMIOS_H': 1,
|
| 476 |
+
'HAVE_TERM_H': 1,
|
| 477 |
+
'HAVE_TGAMMA': 1,
|
| 478 |
+
'HAVE_TIMEGM': 1,
|
| 479 |
+
'HAVE_TIMES': 1,
|
| 480 |
+
'HAVE_TMPFILE': 1,
|
| 481 |
+
'HAVE_TMPNAM': 1,
|
| 482 |
+
'HAVE_TMPNAM_R': 1,
|
| 483 |
+
'HAVE_TM_ZONE': 1,
|
| 484 |
+
'HAVE_TRUNCATE': 1,
|
| 485 |
+
'HAVE_TZNAME': 0,
|
| 486 |
+
'HAVE_UCS4_TCL': 0,
|
| 487 |
+
'HAVE_UNAME': 1,
|
| 488 |
+
'HAVE_UNISTD_H': 1,
|
| 489 |
+
'HAVE_UNLINKAT': 1,
|
| 490 |
+
'HAVE_UNSETENV': 1,
|
| 491 |
+
'HAVE_USABLE_WCHAR_T': 0,
|
| 492 |
+
'HAVE_UTIL_H': 0,
|
| 493 |
+
'HAVE_UTIMENSAT': 1,
|
| 494 |
+
'HAVE_UTIMES': 1,
|
| 495 |
+
'HAVE_UTIME_H': 1,
|
| 496 |
+
'HAVE_WAIT3': 1,
|
| 497 |
+
'HAVE_WAIT4': 1,
|
| 498 |
+
'HAVE_WAITID': 1,
|
| 499 |
+
'HAVE_WAITPID': 1,
|
| 500 |
+
'HAVE_WCHAR_H': 1,
|
| 501 |
+
'HAVE_WCSCOLL': 1,
|
| 502 |
+
'HAVE_WCSFTIME': 1,
|
| 503 |
+
'HAVE_WCSXFRM': 1,
|
| 504 |
+
'HAVE_WMEMCMP': 1,
|
| 505 |
+
'HAVE_WORKING_TZSET': 1,
|
| 506 |
+
'HAVE_WRITEV': 1,
|
| 507 |
+
'HAVE_ZLIB_COPY': 1,
|
| 508 |
+
'HAVE__GETPTY': 0,
|
| 509 |
+
'HOST_GNU_TYPE': 'x86_64-conda-linux-gnu',
|
| 510 |
+
'INCLDIRSTOMAKE': '/workspace/anaconda3/include '
|
| 511 |
+
'/workspace/anaconda3/include '
|
| 512 |
+
'/workspace/anaconda3/include/python3.8 '
|
| 513 |
+
'/workspace/anaconda3/include/python3.8',
|
| 514 |
+
'INCLUDEDIR': '/workspace/anaconda3/include',
|
| 515 |
+
'INCLUDEPY': '/workspace/anaconda3/include/python3.8',
|
| 516 |
+
'INSTALL': '/usr/bin/install -c',
|
| 517 |
+
'INSTALL_DATA': '/usr/bin/install -c -m 644',
|
| 518 |
+
'INSTALL_PROGRAM': '/usr/bin/install -c',
|
| 519 |
+
'INSTALL_SCRIPT': '/usr/bin/install -c',
|
| 520 |
+
'INSTALL_SHARED': '/usr/bin/install -c -m 555',
|
| 521 |
+
'INSTSONAME': 'libpython3.8.a',
|
| 522 |
+
'IO_H': 'Modules/_io/_iomodule.h',
|
| 523 |
+
'IO_OBJS': '\\',
|
| 524 |
+
'LDCXXSHARED': 'x86_64-conda-linux-gnu-c++ -pthread -shared',
|
| 525 |
+
'LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 526 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 527 |
+
'-L/workspace/anaconda3/lib '
|
| 528 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 529 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 530 |
+
'-L/workspace/anaconda3/lib '
|
| 531 |
+
' ',
|
| 532 |
+
'LDLAST': '',
|
| 533 |
+
'LDLIBRARY': 'libpython3.8.a',
|
| 534 |
+
'LDLIBRARYDIR': '',
|
| 535 |
+
'LDSHARED': 'x86_64-conda-linux-gnu-gcc -pthread -shared -Wl,-O2 '
|
| 536 |
+
'-Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now '
|
| 537 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 538 |
+
'-L/workspace/anaconda3/lib '
|
| 539 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 540 |
+
'-Wl,-z,now '
|
| 541 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 542 |
+
'-L/workspace/anaconda3/lib '
|
| 543 |
+
' ',
|
| 544 |
+
'LDVERSION': '3.8',
|
| 545 |
+
'LIBC': '',
|
| 546 |
+
'LIBDEST': '/workspace/anaconda3/lib/python3.8',
|
| 547 |
+
'LIBDIR': '/workspace/anaconda3/lib',
|
| 548 |
+
'LIBFFI_INCLUDEDIR': '/workspace/anaconda3/include',
|
| 549 |
+
'LIBM': '-lm',
|
| 550 |
+
'LIBOBJDIR': 'Python/',
|
| 551 |
+
'LIBOBJS': '',
|
| 552 |
+
'LIBPC': '/workspace/anaconda3/lib/pkgconfig',
|
| 553 |
+
'LIBPL': '/workspace/anaconda3/lib/python3.8/config-3.8-x86_64-linux-gnu',
|
| 554 |
+
'LIBRARY': 'libpython3.8.a',
|
| 555 |
+
'LIBRARY_OBJS': '\\',
|
| 556 |
+
'LIBRARY_OBJS_OMIT_FROZEN': '\\',
|
| 557 |
+
'LIBS': '-lpthread -ldl -lutil -lrt',
|
| 558 |
+
'LIBSUBDIRS': 'tkinter tkinter/test tkinter/test/test_tkinter \\',
|
| 559 |
+
'LINKCC': 'x86_64-conda-linux-gnu-gcc -pthread',
|
| 560 |
+
'LINKFORSHARED': '-Xlinker -export-dynamic',
|
| 561 |
+
'LIPO_32BIT_FLAGS': '',
|
| 562 |
+
'LLVM_PROF_ERR': 'no',
|
| 563 |
+
'LLVM_PROF_FILE': '',
|
| 564 |
+
'LLVM_PROF_MERGER': 'true',
|
| 565 |
+
'LN': 'ln',
|
| 566 |
+
'LOCALMODLIBS': '',
|
| 567 |
+
'LOG1P_DROPS_ZERO_SIGN': 0,
|
| 568 |
+
'MACHDEP': 'linux',
|
| 569 |
+
'MACHDEPPATH': ':',
|
| 570 |
+
'MACHDEP_OBJS': '',
|
| 571 |
+
'MACHDESTLIB': '/workspace/anaconda3/lib/python3.8',
|
| 572 |
+
'MACOSX_DEPLOYMENT_TARGET': '',
|
| 573 |
+
'MAINCC': 'x86_64-conda-linux-gnu-gcc -pthread',
|
| 574 |
+
'MAJOR_IN_MKDEV': 0,
|
| 575 |
+
'MAJOR_IN_SYSMACROS': 0,
|
| 576 |
+
'MAKESETUP': '/tmp/build/80754af9/python_1510184704423/work/Modules/makesetup',
|
| 577 |
+
'MANDIR': '/workspace/anaconda3/share/man',
|
| 578 |
+
'MKDIR_P': '/bin/mkdir -p',
|
| 579 |
+
'MODLIBS': '',
|
| 580 |
+
'MODNAMES': '_thread posix errno pwd _sre _codecs _weakref _functools '
|
| 581 |
+
'_operator _collections itertools atexit _signal _stat time '
|
| 582 |
+
'_locale _io zipimport faulthandler _tracemalloc _symtable '
|
| 583 |
+
'xxsubtype',
|
| 584 |
+
'MODOBJS': 'Modules/_threadmodule.o Modules/posixmodule.o '
|
| 585 |
+
'Modules/errnomodule.o Modules/pwdmodule.o Modules/_sre.o '
|
| 586 |
+
'Modules/_codecsmodule.o Modules/_weakref.o '
|
| 587 |
+
'Modules/_functoolsmodule.o Modules/_operator.o '
|
| 588 |
+
'Modules/_collectionsmodule.o Modules/itertoolsmodule.o '
|
| 589 |
+
'Modules/atexitmodule.o Modules/signalmodule.o Modules/_stat.o '
|
| 590 |
+
'Modules/timemodule.o Modules/_localemodule.o '
|
| 591 |
+
'Modules/_iomodule.o Modules/iobase.o Modules/fileio.o '
|
| 592 |
+
'Modules/bytesio.o Modules/bufferedio.o Modules/textio.o '
|
| 593 |
+
'Modules/stringio.o Modules/zipimport.o Modules/faulthandler.o '
|
| 594 |
+
'Modules/_tracemalloc.o Modules/hashtable.o '
|
| 595 |
+
'Modules/symtablemodule.o Modules/xxsubtype.o',
|
| 596 |
+
'MODULE_OBJS': '\\',
|
| 597 |
+
'MULTIARCH': 'x86_64-linux-gnu',
|
| 598 |
+
'MULTIARCH_CPPFLAGS': '-DMULTIARCH=\\"x86_64-linux-gnu\\"',
|
| 599 |
+
'MVWDELCH_IS_EXPRESSION': 1,
|
| 600 |
+
'NO_AS_NEEDED': '-Wl,--no-as-needed',
|
| 601 |
+
'OBJECT_OBJS': '\\',
|
| 602 |
+
'OPT': '-DNDEBUG -fwrapv -O2 -Wall -Wstrict-prototypes',
|
| 603 |
+
'OTHER_LIBTOOL_OPT': '',
|
| 604 |
+
'PACKAGE_BUGREPORT': 0,
|
| 605 |
+
'PACKAGE_NAME': 0,
|
| 606 |
+
'PACKAGE_STRING': 0,
|
| 607 |
+
'PACKAGE_TARNAME': 0,
|
| 608 |
+
'PACKAGE_URL': 0,
|
| 609 |
+
'PACKAGE_VERSION': 0,
|
| 610 |
+
'PARSER_HEADERS': '\\',
|
| 611 |
+
'PARSER_OBJS': '\\ Parser/myreadline.o Parser/parsetok.o Parser/tokenizer.o',
|
| 612 |
+
'PGEN': 'Parser/pgen',
|
| 613 |
+
'PGENOBJS': '\\ \\',
|
| 614 |
+
'PGOBJS': '\\',
|
| 615 |
+
'PGO_PROF_GEN_FLAG': '-fprofile-generate',
|
| 616 |
+
'PGO_PROF_USE_FLAG': ' ',
|
| 617 |
+
'PLATDIR': '',
|
| 618 |
+
'POBJS': '\\',
|
| 619 |
+
'POSIX_SEMAPHORES_NOT_ENABLED': 0,
|
| 620 |
+
'PROFILE_TASK': '-m test.regrtest --pgo',
|
| 621 |
+
'PTHREAD_SYSTEM_SCHED_SUPPORTED': 1,
|
| 622 |
+
'PURIFY': '',
|
| 623 |
+
'PY3LIBRARY': '',
|
| 624 |
+
'PYLONG_BITS_IN_DIGIT': 0,
|
| 625 |
+
'PYTHON': 'python',
|
| 626 |
+
'PYTHONFRAMEWORK': '',
|
| 627 |
+
'PYTHONFRAMEWORKDIR': 'no-framework',
|
| 628 |
+
'PYTHONFRAMEWORKINSTALLDIR': '',
|
| 629 |
+
'PYTHONFRAMEWORKPREFIX': '',
|
| 630 |
+
'PYTHONPATH': ':',
|
| 631 |
+
'PYTHON_FOR_BUILD': './python -E',
|
| 632 |
+
'PYTHON_FOR_REGEN': 'python3.8',
|
| 633 |
+
'PYTHON_HEADERS': '\\',
|
| 634 |
+
'PYTHON_OBJS': '\\',
|
| 635 |
+
'PY_BUILD_ENVIRON': '',
|
| 636 |
+
'PY_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall '
|
| 637 |
+
'-Wstrict-prototypes -march=nocona -mtune=haswell '
|
| 638 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 '
|
| 639 |
+
'-pipe '
|
| 640 |
+
' -march=nocona -mtune=haswell '
|
| 641 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 '
|
| 642 |
+
'-pipe '
|
| 643 |
+
' ',
|
| 644 |
+
'PY_CFLAGS_NODIST': '-std=c99 -Wextra -Wno-unused-result '
|
| 645 |
+
'-Wno-unused-parameter -Wno-missing-field-initializers '
|
| 646 |
+
'-march=nocona -mtune=haswell -ftree-vectorize -fPIC '
|
| 647 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 648 |
+
' '
|
| 649 |
+
' '
|
| 650 |
+
' '
|
| 651 |
+
' ',
|
| 652 |
+
'PY_CORE_CFLAGS': '-Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 '
|
| 653 |
+
'-Wall -Wstrict-prototypes -march=nocona -mtune=haswell '
|
| 654 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt '
|
| 655 |
+
'-O2 -pipe '
|
| 656 |
+
' -march=nocona -mtune=haswell '
|
| 657 |
+
'-ftree-vectorize -fPIC -fstack-protector-strong -fno-plt '
|
| 658 |
+
'-O2 -pipe '
|
| 659 |
+
' -std=c99 -Wextra '
|
| 660 |
+
'-Wno-unused-result -Wno-unused-parameter '
|
| 661 |
+
'-Wno-missing-field-initializers -march=nocona '
|
| 662 |
+
'-mtune=haswell -ftree-vectorize -fPIC '
|
| 663 |
+
'-fstack-protector-strong -fno-plt -O2 -pipe '
|
| 664 |
+
' '
|
| 665 |
+
' '
|
| 666 |
+
' '
|
| 667 |
+
'-IObjects -IInclude -IPython -I. '
|
| 668 |
+
'-I/tmp/build/80754af9/python_1510184704423/work/Include '
|
| 669 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 670 |
+
'-I/workspace/anaconda3/include '
|
| 671 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 672 |
+
'-I/workspace/anaconda3/include '
|
| 673 |
+
'-DPy_BUILD_CORE',
|
| 674 |
+
'PY_CPPFLAGS': '-IObjects -IInclude -IPython -I. '
|
| 675 |
+
'-I/tmp/build/80754af9/python_1510184704423/work/Include '
|
| 676 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 677 |
+
'-I/workspace/anaconda3/include '
|
| 678 |
+
'-D_FORTIFY_SOURCE=2 -O2 '
|
| 679 |
+
'-I/workspace/anaconda3/include',
|
| 680 |
+
'PY_FORMAT_SIZE_T': '"z"',
|
| 681 |
+
'PY_LDFLAGS': '-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 682 |
+
'-Wl,-z,now '
|
| 683 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 684 |
+
'-L/workspace/anaconda3/lib '
|
| 685 |
+
'-Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro '
|
| 686 |
+
'-Wl,-z,now '
|
| 687 |
+
'-Wl,-rpath,/workspace/anaconda3/lib '
|
| 688 |
+
'-L/workspace/anaconda3/lib '
|
| 689 |
+
' '
|
| 690 |
+
'',
|
| 691 |
+
'Py_DEBUG': 0,
|
| 692 |
+
'Py_ENABLE_SHARED': 0,
|
| 693 |
+
'Py_HASH_ALGORITHM': 0,
|
| 694 |
+
'QUICKTESTOPTS': '-x test_subprocess test_io test_lib2to3 \\',
|
| 695 |
+
'RANLIB': 'x86_64-conda-linux-gnu-ranlib',
|
| 696 |
+
'READELF': 'x86_64-conda-linux-gnu-readelf',
|
| 697 |
+
'RESSRCDIR': 'Mac/Resources/framework',
|
| 698 |
+
'RETSIGTYPE': 'void',
|
| 699 |
+
'RUNSHARED': '',
|
| 700 |
+
'SCRIPTDIR': '/workspace/anaconda3/lib',
|
| 701 |
+
'SETPGRP_HAVE_ARG': 0,
|
| 702 |
+
'SGI_ABI': '',
|
| 703 |
+
'SHELL': '/bin/sh',
|
| 704 |
+
'SHLIBS': '-lpthread -ldl -lutil -lrt',
|
| 705 |
+
'SHLIB_SUFFIX': '.so',
|
| 706 |
+
'SIGNED_RIGHT_SHIFT_ZERO_FILLS': 0,
|
| 707 |
+
'SITEPATH': '',
|
| 708 |
+
'SIZEOF_DOUBLE': 8,
|
| 709 |
+
'SIZEOF_FLOAT': 4,
|
| 710 |
+
'SIZEOF_FPOS_T': 16,
|
| 711 |
+
'SIZEOF_INT': 4,
|
| 712 |
+
'SIZEOF_LONG': 8,
|
| 713 |
+
'SIZEOF_LONG_DOUBLE': 16,
|
| 714 |
+
'SIZEOF_LONG_LONG': 8,
|
| 715 |
+
'SIZEOF_OFF_T': 8,
|
| 716 |
+
'SIZEOF_PID_T': 4,
|
| 717 |
+
'SIZEOF_PTHREAD_T': 8,
|
| 718 |
+
'SIZEOF_SHORT': 2,
|
| 719 |
+
'SIZEOF_SIZE_T': 8,
|
| 720 |
+
'SIZEOF_TIME_T': 8,
|
| 721 |
+
'SIZEOF_UINTPTR_T': 8,
|
| 722 |
+
'SIZEOF_VOID_P': 8,
|
| 723 |
+
'SIZEOF_WCHAR_T': 4,
|
| 724 |
+
'SIZEOF__BOOL': 1,
|
| 725 |
+
'SOABI': 'cpython-38-x86_64-linux-gnu',
|
| 726 |
+
'SRCDIRS': 'Parser Grammar Objects Python Modules Mac Programs',
|
| 727 |
+
'SRC_GDB_HOOKS': '/tmp/build/80754af9/python_1510184704423/work/Tools/gdb/libpython.py',
|
| 728 |
+
'STDC_HEADERS': 1,
|
| 729 |
+
'STRICT_SYSV_CURSES': "/* Don't use ncurses extensions */",
|
| 730 |
+
'STRIPFLAG': '-s',
|
| 731 |
+
'SUBDIRS': '',
|
| 732 |
+
'SUBDIRSTOO': 'Include Lib Misc',
|
| 733 |
+
'SYSLIBS': '-lm',
|
| 734 |
+
'SYS_SELECT_WITH_SYS_TIME': 1,
|
| 735 |
+
'TANH_PRESERVES_ZERO_SIGN': 1,
|
| 736 |
+
'TCLTK_INCLUDES': '-I/workspace/anaconda3/include',
|
| 737 |
+
'TCLTK_LIBS': '-L/workspace/anaconda3/lib '
|
| 738 |
+
'-ltcl8.6 -ltk8.6',
|
| 739 |
+
'TESTOPTS': '',
|
| 740 |
+
'TESTPATH': '',
|
| 741 |
+
'TESTPYTHON': './python',
|
| 742 |
+
'TESTPYTHONOPTS': '',
|
| 743 |
+
'TESTRUNNER': './python '
|
| 744 |
+
'/tmp/build/80754af9/python_1510184704423/work/Tools/scripts/run_tests.py',
|
| 745 |
+
'TESTTIMEOUT': 1200,
|
| 746 |
+
'THREADOBJ': 'Python/thread.o',
|
| 747 |
+
'TIMEMODULE_LIB': 'rt',
|
| 748 |
+
'TIME_WITH_SYS_TIME': 1,
|
| 749 |
+
'TM_IN_SYS_TIME': 0,
|
| 750 |
+
'UNICODE_DEPS': '\\',
|
| 751 |
+
'UNIVERSALSDK': '',
|
| 752 |
+
'USE_COMPUTED_GOTOS': 1,
|
| 753 |
+
'USE_INLINE': 1,
|
| 754 |
+
'VERSION': '3.8',
|
| 755 |
+
'VPATH': '/tmp/build/80754af9/python_1510184704423/work',
|
| 756 |
+
'WANT_SIGFPE_HANDLER': 0,
|
| 757 |
+
'WINDOW_HAS_FLAGS': 1,
|
| 758 |
+
'WITH_DOC_STRINGS': 1,
|
| 759 |
+
'WITH_DTRACE': 0,
|
| 760 |
+
'WITH_DYLD': 0,
|
| 761 |
+
'WITH_LIBINTL': 0,
|
| 762 |
+
'WITH_NEXT_FRAMEWORK': 0,
|
| 763 |
+
'WITH_PYMALLOC': 1,
|
| 764 |
+
'WITH_THREAD': 1,
|
| 765 |
+
'WITH_VALGRIND': 0,
|
| 766 |
+
'X87_DOUBLE_ROUNDING': 0,
|
| 767 |
+
'XMLLIBSUBDIRS': 'xml xml/dom xml/etree xml/parsers xml/sax',
|
| 768 |
+
'abs_builddir': '/tmp/build/80754af9/python_1510184704423/work/build-static',
|
| 769 |
+
'abs_srcdir': '/tmp/build/80754af9/python_1510184704423/work',
|
| 770 |
+
'datarootdir': '/workspace/anaconda3/share',
|
| 771 |
+
'exec_prefix': '/workspace/anaconda3',
|
| 772 |
+
'prefix': '/workspace/anaconda3',
|
| 773 |
+
'srcdir': '/tmp/build/80754af9/python_1510184704423/work'}
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/antigravity.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
import webbrowser
|
| 3 |
+
import hashlib
|
| 4 |
+
|
| 5 |
+
webbrowser.open("https://xkcd.com/353/")
|
| 6 |
+
|
| 7 |
+
def geohash(latitude, longitude, datedow):
|
| 8 |
+
'''Compute geohash() using the Munroe algorithm.
|
| 9 |
+
|
| 10 |
+
>>> geohash(37.421542, -122.085589, b'2005-05-26-10458.68')
|
| 11 |
+
37.857713 -122.544543
|
| 12 |
+
|
| 13 |
+
'''
|
| 14 |
+
# https://xkcd.com/426/
|
| 15 |
+
h = hashlib.md5(datedow).hexdigest()
|
| 16 |
+
p, q = [('%f' % float.fromhex('0.' + x)) for x in (h[:16], h[16:32])]
|
| 17 |
+
print('%d%s %d%s' % (latitude, p[1:], longitude, q[1:]))
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/ast.py
ADDED
|
@@ -0,0 +1,547 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
ast
|
| 3 |
+
~~~
|
| 4 |
+
|
| 5 |
+
The `ast` module helps Python applications to process trees of the Python
|
| 6 |
+
abstract syntax grammar. The abstract syntax itself might change with
|
| 7 |
+
each Python release; this module helps to find out programmatically what
|
| 8 |
+
the current grammar looks like and allows modifications of it.
|
| 9 |
+
|
| 10 |
+
An abstract syntax tree can be generated by passing `ast.PyCF_ONLY_AST` as
|
| 11 |
+
a flag to the `compile()` builtin function or by using the `parse()`
|
| 12 |
+
function from this module. The result will be a tree of objects whose
|
| 13 |
+
classes all inherit from `ast.AST`.
|
| 14 |
+
|
| 15 |
+
A modified abstract syntax tree can be compiled into a Python code object
|
| 16 |
+
using the built-in `compile()` function.
|
| 17 |
+
|
| 18 |
+
Additionally various helper functions are provided that make working with
|
| 19 |
+
the trees simpler. The main intention of the helper functions and this
|
| 20 |
+
module in general is to provide an easy to use interface for libraries
|
| 21 |
+
that work tightly with the python syntax (template engines for example).
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
:copyright: Copyright 2008 by Armin Ronacher.
|
| 25 |
+
:license: Python License.
|
| 26 |
+
"""
|
| 27 |
+
from _ast import *
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def parse(source, filename='<unknown>', mode='exec', *,
|
| 31 |
+
type_comments=False, feature_version=None):
|
| 32 |
+
"""
|
| 33 |
+
Parse the source into an AST node.
|
| 34 |
+
Equivalent to compile(source, filename, mode, PyCF_ONLY_AST).
|
| 35 |
+
Pass type_comments=True to get back type comments where the syntax allows.
|
| 36 |
+
"""
|
| 37 |
+
flags = PyCF_ONLY_AST
|
| 38 |
+
if type_comments:
|
| 39 |
+
flags |= PyCF_TYPE_COMMENTS
|
| 40 |
+
if isinstance(feature_version, tuple):
|
| 41 |
+
major, minor = feature_version # Should be a 2-tuple.
|
| 42 |
+
assert major == 3
|
| 43 |
+
feature_version = minor
|
| 44 |
+
elif feature_version is None:
|
| 45 |
+
feature_version = -1
|
| 46 |
+
# Else it should be an int giving the minor version for 3.x.
|
| 47 |
+
return compile(source, filename, mode, flags,
|
| 48 |
+
_feature_version=feature_version)
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def literal_eval(node_or_string):
|
| 52 |
+
"""
|
| 53 |
+
Safely evaluate an expression node or a string containing a Python
|
| 54 |
+
expression. The string or node provided may only consist of the following
|
| 55 |
+
Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
|
| 56 |
+
sets, booleans, and None.
|
| 57 |
+
"""
|
| 58 |
+
if isinstance(node_or_string, str):
|
| 59 |
+
node_or_string = parse(node_or_string, mode='eval')
|
| 60 |
+
if isinstance(node_or_string, Expression):
|
| 61 |
+
node_or_string = node_or_string.body
|
| 62 |
+
def _raise_malformed_node(node):
|
| 63 |
+
raise ValueError(f'malformed node or string: {node!r}')
|
| 64 |
+
def _convert_num(node):
|
| 65 |
+
if not isinstance(node, Constant) or type(node.value) not in (int, float, complex):
|
| 66 |
+
_raise_malformed_node(node)
|
| 67 |
+
return node.value
|
| 68 |
+
def _convert_signed_num(node):
|
| 69 |
+
if isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)):
|
| 70 |
+
operand = _convert_num(node.operand)
|
| 71 |
+
if isinstance(node.op, UAdd):
|
| 72 |
+
return + operand
|
| 73 |
+
else:
|
| 74 |
+
return - operand
|
| 75 |
+
return _convert_num(node)
|
| 76 |
+
def _convert(node):
|
| 77 |
+
if isinstance(node, Constant):
|
| 78 |
+
return node.value
|
| 79 |
+
elif isinstance(node, Tuple):
|
| 80 |
+
return tuple(map(_convert, node.elts))
|
| 81 |
+
elif isinstance(node, List):
|
| 82 |
+
return list(map(_convert, node.elts))
|
| 83 |
+
elif isinstance(node, Set):
|
| 84 |
+
return set(map(_convert, node.elts))
|
| 85 |
+
elif isinstance(node, Dict):
|
| 86 |
+
if len(node.keys) != len(node.values):
|
| 87 |
+
_raise_malformed_node(node)
|
| 88 |
+
return dict(zip(map(_convert, node.keys),
|
| 89 |
+
map(_convert, node.values)))
|
| 90 |
+
elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)):
|
| 91 |
+
left = _convert_signed_num(node.left)
|
| 92 |
+
right = _convert_num(node.right)
|
| 93 |
+
if isinstance(left, (int, float)) and isinstance(right, complex):
|
| 94 |
+
if isinstance(node.op, Add):
|
| 95 |
+
return left + right
|
| 96 |
+
else:
|
| 97 |
+
return left - right
|
| 98 |
+
return _convert_signed_num(node)
|
| 99 |
+
return _convert(node_or_string)
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def dump(node, annotate_fields=True, include_attributes=False):
|
| 103 |
+
"""
|
| 104 |
+
Return a formatted dump of the tree in node. This is mainly useful for
|
| 105 |
+
debugging purposes. If annotate_fields is true (by default),
|
| 106 |
+
the returned string will show the names and the values for fields.
|
| 107 |
+
If annotate_fields is false, the result string will be more compact by
|
| 108 |
+
omitting unambiguous field names. Attributes such as line
|
| 109 |
+
numbers and column offsets are not dumped by default. If this is wanted,
|
| 110 |
+
include_attributes can be set to true.
|
| 111 |
+
"""
|
| 112 |
+
def _format(node):
|
| 113 |
+
if isinstance(node, AST):
|
| 114 |
+
args = []
|
| 115 |
+
keywords = annotate_fields
|
| 116 |
+
for field in node._fields:
|
| 117 |
+
try:
|
| 118 |
+
value = getattr(node, field)
|
| 119 |
+
except AttributeError:
|
| 120 |
+
keywords = True
|
| 121 |
+
else:
|
| 122 |
+
if keywords:
|
| 123 |
+
args.append('%s=%s' % (field, _format(value)))
|
| 124 |
+
else:
|
| 125 |
+
args.append(_format(value))
|
| 126 |
+
if include_attributes and node._attributes:
|
| 127 |
+
for a in node._attributes:
|
| 128 |
+
try:
|
| 129 |
+
args.append('%s=%s' % (a, _format(getattr(node, a))))
|
| 130 |
+
except AttributeError:
|
| 131 |
+
pass
|
| 132 |
+
return '%s(%s)' % (node.__class__.__name__, ', '.join(args))
|
| 133 |
+
elif isinstance(node, list):
|
| 134 |
+
return '[%s]' % ', '.join(_format(x) for x in node)
|
| 135 |
+
return repr(node)
|
| 136 |
+
if not isinstance(node, AST):
|
| 137 |
+
raise TypeError('expected AST, got %r' % node.__class__.__name__)
|
| 138 |
+
return _format(node)
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def copy_location(new_node, old_node):
|
| 142 |
+
"""
|
| 143 |
+
Copy source location (`lineno`, `col_offset`, `end_lineno`, and `end_col_offset`
|
| 144 |
+
attributes) from *old_node* to *new_node* if possible, and return *new_node*.
|
| 145 |
+
"""
|
| 146 |
+
for attr in 'lineno', 'col_offset', 'end_lineno', 'end_col_offset':
|
| 147 |
+
if attr in old_node._attributes and attr in new_node._attributes:
|
| 148 |
+
value = getattr(old_node, attr, None)
|
| 149 |
+
# end_lineno and end_col_offset are optional attributes, and they
|
| 150 |
+
# should be copied whether the value is None or not.
|
| 151 |
+
if value is not None or (
|
| 152 |
+
hasattr(old_node, attr) and attr.startswith("end_")
|
| 153 |
+
):
|
| 154 |
+
setattr(new_node, attr, value)
|
| 155 |
+
return new_node
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
def fix_missing_locations(node):
|
| 159 |
+
"""
|
| 160 |
+
When you compile a node tree with compile(), the compiler expects lineno and
|
| 161 |
+
col_offset attributes for every node that supports them. This is rather
|
| 162 |
+
tedious to fill in for generated nodes, so this helper adds these attributes
|
| 163 |
+
recursively where not already set, by setting them to the values of the
|
| 164 |
+
parent node. It works recursively starting at *node*.
|
| 165 |
+
"""
|
| 166 |
+
def _fix(node, lineno, col_offset, end_lineno, end_col_offset):
|
| 167 |
+
if 'lineno' in node._attributes:
|
| 168 |
+
if not hasattr(node, 'lineno'):
|
| 169 |
+
node.lineno = lineno
|
| 170 |
+
else:
|
| 171 |
+
lineno = node.lineno
|
| 172 |
+
if 'end_lineno' in node._attributes:
|
| 173 |
+
if not hasattr(node, 'end_lineno'):
|
| 174 |
+
node.end_lineno = end_lineno
|
| 175 |
+
else:
|
| 176 |
+
end_lineno = node.end_lineno
|
| 177 |
+
if 'col_offset' in node._attributes:
|
| 178 |
+
if not hasattr(node, 'col_offset'):
|
| 179 |
+
node.col_offset = col_offset
|
| 180 |
+
else:
|
| 181 |
+
col_offset = node.col_offset
|
| 182 |
+
if 'end_col_offset' in node._attributes:
|
| 183 |
+
if not hasattr(node, 'end_col_offset'):
|
| 184 |
+
node.end_col_offset = end_col_offset
|
| 185 |
+
else:
|
| 186 |
+
end_col_offset = node.end_col_offset
|
| 187 |
+
for child in iter_child_nodes(node):
|
| 188 |
+
_fix(child, lineno, col_offset, end_lineno, end_col_offset)
|
| 189 |
+
_fix(node, 1, 0, 1, 0)
|
| 190 |
+
return node
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
def increment_lineno(node, n=1):
|
| 194 |
+
"""
|
| 195 |
+
Increment the line number and end line number of each node in the tree
|
| 196 |
+
starting at *node* by *n*. This is useful to "move code" to a different
|
| 197 |
+
location in a file.
|
| 198 |
+
"""
|
| 199 |
+
for child in walk(node):
|
| 200 |
+
if 'lineno' in child._attributes:
|
| 201 |
+
child.lineno = getattr(child, 'lineno', 0) + n
|
| 202 |
+
if (
|
| 203 |
+
"end_lineno" in child._attributes
|
| 204 |
+
and (end_lineno := getattr(child, "end_lineno", 0)) is not None
|
| 205 |
+
):
|
| 206 |
+
child.end_lineno = end_lineno + n
|
| 207 |
+
return node
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
def iter_fields(node):
|
| 211 |
+
"""
|
| 212 |
+
Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields``
|
| 213 |
+
that is present on *node*.
|
| 214 |
+
"""
|
| 215 |
+
for field in node._fields:
|
| 216 |
+
try:
|
| 217 |
+
yield field, getattr(node, field)
|
| 218 |
+
except AttributeError:
|
| 219 |
+
pass
|
| 220 |
+
|
| 221 |
+
|
| 222 |
+
def iter_child_nodes(node):
|
| 223 |
+
"""
|
| 224 |
+
Yield all direct child nodes of *node*, that is, all fields that are nodes
|
| 225 |
+
and all items of fields that are lists of nodes.
|
| 226 |
+
"""
|
| 227 |
+
for name, field in iter_fields(node):
|
| 228 |
+
if isinstance(field, AST):
|
| 229 |
+
yield field
|
| 230 |
+
elif isinstance(field, list):
|
| 231 |
+
for item in field:
|
| 232 |
+
if isinstance(item, AST):
|
| 233 |
+
yield item
|
| 234 |
+
|
| 235 |
+
|
| 236 |
+
def get_docstring(node, clean=True):
|
| 237 |
+
"""
|
| 238 |
+
Return the docstring for the given node or None if no docstring can
|
| 239 |
+
be found. If the node provided does not have docstrings a TypeError
|
| 240 |
+
will be raised.
|
| 241 |
+
|
| 242 |
+
If *clean* is `True`, all tabs are expanded to spaces and any whitespace
|
| 243 |
+
that can be uniformly removed from the second line onwards is removed.
|
| 244 |
+
"""
|
| 245 |
+
if not isinstance(node, (AsyncFunctionDef, FunctionDef, ClassDef, Module)):
|
| 246 |
+
raise TypeError("%r can't have docstrings" % node.__class__.__name__)
|
| 247 |
+
if not(node.body and isinstance(node.body[0], Expr)):
|
| 248 |
+
return None
|
| 249 |
+
node = node.body[0].value
|
| 250 |
+
if isinstance(node, Str):
|
| 251 |
+
text = node.s
|
| 252 |
+
elif isinstance(node, Constant) and isinstance(node.value, str):
|
| 253 |
+
text = node.value
|
| 254 |
+
else:
|
| 255 |
+
return None
|
| 256 |
+
if clean:
|
| 257 |
+
import inspect
|
| 258 |
+
text = inspect.cleandoc(text)
|
| 259 |
+
return text
|
| 260 |
+
|
| 261 |
+
|
| 262 |
+
def _splitlines_no_ff(source):
|
| 263 |
+
"""Split a string into lines ignoring form feed and other chars.
|
| 264 |
+
|
| 265 |
+
This mimics how the Python parser splits source code.
|
| 266 |
+
"""
|
| 267 |
+
idx = 0
|
| 268 |
+
lines = []
|
| 269 |
+
next_line = ''
|
| 270 |
+
while idx < len(source):
|
| 271 |
+
c = source[idx]
|
| 272 |
+
next_line += c
|
| 273 |
+
idx += 1
|
| 274 |
+
# Keep \r\n together
|
| 275 |
+
if c == '\r' and idx < len(source) and source[idx] == '\n':
|
| 276 |
+
next_line += '\n'
|
| 277 |
+
idx += 1
|
| 278 |
+
if c in '\r\n':
|
| 279 |
+
lines.append(next_line)
|
| 280 |
+
next_line = ''
|
| 281 |
+
|
| 282 |
+
if next_line:
|
| 283 |
+
lines.append(next_line)
|
| 284 |
+
return lines
|
| 285 |
+
|
| 286 |
+
|
| 287 |
+
def _pad_whitespace(source):
|
| 288 |
+
r"""Replace all chars except '\f\t' in a line with spaces."""
|
| 289 |
+
result = ''
|
| 290 |
+
for c in source:
|
| 291 |
+
if c in '\f\t':
|
| 292 |
+
result += c
|
| 293 |
+
else:
|
| 294 |
+
result += ' '
|
| 295 |
+
return result
|
| 296 |
+
|
| 297 |
+
|
| 298 |
+
def get_source_segment(source, node, *, padded=False):
|
| 299 |
+
"""Get source code segment of the *source* that generated *node*.
|
| 300 |
+
|
| 301 |
+
If some location information (`lineno`, `end_lineno`, `col_offset`,
|
| 302 |
+
or `end_col_offset`) is missing, return None.
|
| 303 |
+
|
| 304 |
+
If *padded* is `True`, the first line of a multi-line statement will
|
| 305 |
+
be padded with spaces to match its original position.
|
| 306 |
+
"""
|
| 307 |
+
try:
|
| 308 |
+
lineno = node.lineno - 1
|
| 309 |
+
end_lineno = node.end_lineno - 1
|
| 310 |
+
col_offset = node.col_offset
|
| 311 |
+
end_col_offset = node.end_col_offset
|
| 312 |
+
except AttributeError:
|
| 313 |
+
return None
|
| 314 |
+
|
| 315 |
+
lines = _splitlines_no_ff(source)
|
| 316 |
+
if end_lineno == lineno:
|
| 317 |
+
return lines[lineno].encode()[col_offset:end_col_offset].decode()
|
| 318 |
+
|
| 319 |
+
if padded:
|
| 320 |
+
padding = _pad_whitespace(lines[lineno].encode()[:col_offset].decode())
|
| 321 |
+
else:
|
| 322 |
+
padding = ''
|
| 323 |
+
|
| 324 |
+
first = padding + lines[lineno].encode()[col_offset:].decode()
|
| 325 |
+
last = lines[end_lineno].encode()[:end_col_offset].decode()
|
| 326 |
+
lines = lines[lineno+1:end_lineno]
|
| 327 |
+
|
| 328 |
+
lines.insert(0, first)
|
| 329 |
+
lines.append(last)
|
| 330 |
+
return ''.join(lines)
|
| 331 |
+
|
| 332 |
+
|
| 333 |
+
def walk(node):
|
| 334 |
+
"""
|
| 335 |
+
Recursively yield all descendant nodes in the tree starting at *node*
|
| 336 |
+
(including *node* itself), in no specified order. This is useful if you
|
| 337 |
+
only want to modify nodes in place and don't care about the context.
|
| 338 |
+
"""
|
| 339 |
+
from collections import deque
|
| 340 |
+
todo = deque([node])
|
| 341 |
+
while todo:
|
| 342 |
+
node = todo.popleft()
|
| 343 |
+
todo.extend(iter_child_nodes(node))
|
| 344 |
+
yield node
|
| 345 |
+
|
| 346 |
+
|
| 347 |
+
class NodeVisitor(object):
|
| 348 |
+
"""
|
| 349 |
+
A node visitor base class that walks the abstract syntax tree and calls a
|
| 350 |
+
visitor function for every node found. This function may return a value
|
| 351 |
+
which is forwarded by the `visit` method.
|
| 352 |
+
|
| 353 |
+
This class is meant to be subclassed, with the subclass adding visitor
|
| 354 |
+
methods.
|
| 355 |
+
|
| 356 |
+
Per default the visitor functions for the nodes are ``'visit_'`` +
|
| 357 |
+
class name of the node. So a `TryFinally` node visit function would
|
| 358 |
+
be `visit_TryFinally`. This behavior can be changed by overriding
|
| 359 |
+
the `visit` method. If no visitor function exists for a node
|
| 360 |
+
(return value `None`) the `generic_visit` visitor is used instead.
|
| 361 |
+
|
| 362 |
+
Don't use the `NodeVisitor` if you want to apply changes to nodes during
|
| 363 |
+
traversing. For this a special visitor exists (`NodeTransformer`) that
|
| 364 |
+
allows modifications.
|
| 365 |
+
"""
|
| 366 |
+
|
| 367 |
+
def visit(self, node):
|
| 368 |
+
"""Visit a node."""
|
| 369 |
+
method = 'visit_' + node.__class__.__name__
|
| 370 |
+
visitor = getattr(self, method, self.generic_visit)
|
| 371 |
+
return visitor(node)
|
| 372 |
+
|
| 373 |
+
def generic_visit(self, node):
|
| 374 |
+
"""Called if no explicit visitor function exists for a node."""
|
| 375 |
+
for field, value in iter_fields(node):
|
| 376 |
+
if isinstance(value, list):
|
| 377 |
+
for item in value:
|
| 378 |
+
if isinstance(item, AST):
|
| 379 |
+
self.visit(item)
|
| 380 |
+
elif isinstance(value, AST):
|
| 381 |
+
self.visit(value)
|
| 382 |
+
|
| 383 |
+
def visit_Constant(self, node):
|
| 384 |
+
value = node.value
|
| 385 |
+
type_name = _const_node_type_names.get(type(value))
|
| 386 |
+
if type_name is None:
|
| 387 |
+
for cls, name in _const_node_type_names.items():
|
| 388 |
+
if isinstance(value, cls):
|
| 389 |
+
type_name = name
|
| 390 |
+
break
|
| 391 |
+
if type_name is not None:
|
| 392 |
+
method = 'visit_' + type_name
|
| 393 |
+
try:
|
| 394 |
+
visitor = getattr(self, method)
|
| 395 |
+
except AttributeError:
|
| 396 |
+
pass
|
| 397 |
+
else:
|
| 398 |
+
import warnings
|
| 399 |
+
warnings.warn(f"{method} is deprecated; add visit_Constant",
|
| 400 |
+
PendingDeprecationWarning, 2)
|
| 401 |
+
return visitor(node)
|
| 402 |
+
return self.generic_visit(node)
|
| 403 |
+
|
| 404 |
+
|
| 405 |
+
class NodeTransformer(NodeVisitor):
|
| 406 |
+
"""
|
| 407 |
+
A :class:`NodeVisitor` subclass that walks the abstract syntax tree and
|
| 408 |
+
allows modification of nodes.
|
| 409 |
+
|
| 410 |
+
The `NodeTransformer` will walk the AST and use the return value of the
|
| 411 |
+
visitor methods to replace or remove the old node. If the return value of
|
| 412 |
+
the visitor method is ``None``, the node will be removed from its location,
|
| 413 |
+
otherwise it is replaced with the return value. The return value may be the
|
| 414 |
+
original node in which case no replacement takes place.
|
| 415 |
+
|
| 416 |
+
Here is an example transformer that rewrites all occurrences of name lookups
|
| 417 |
+
(``foo``) to ``data['foo']``::
|
| 418 |
+
|
| 419 |
+
class RewriteName(NodeTransformer):
|
| 420 |
+
|
| 421 |
+
def visit_Name(self, node):
|
| 422 |
+
return Subscript(
|
| 423 |
+
value=Name(id='data', ctx=Load()),
|
| 424 |
+
slice=Index(value=Str(s=node.id)),
|
| 425 |
+
ctx=node.ctx
|
| 426 |
+
)
|
| 427 |
+
|
| 428 |
+
Keep in mind that if the node you're operating on has child nodes you must
|
| 429 |
+
either transform the child nodes yourself or call the :meth:`generic_visit`
|
| 430 |
+
method for the node first.
|
| 431 |
+
|
| 432 |
+
For nodes that were part of a collection of statements (that applies to all
|
| 433 |
+
statement nodes), the visitor may also return a list of nodes rather than
|
| 434 |
+
just a single node.
|
| 435 |
+
|
| 436 |
+
Usually you use the transformer like this::
|
| 437 |
+
|
| 438 |
+
node = YourTransformer().visit(node)
|
| 439 |
+
"""
|
| 440 |
+
|
| 441 |
+
def generic_visit(self, node):
|
| 442 |
+
for field, old_value in iter_fields(node):
|
| 443 |
+
if isinstance(old_value, list):
|
| 444 |
+
new_values = []
|
| 445 |
+
for value in old_value:
|
| 446 |
+
if isinstance(value, AST):
|
| 447 |
+
value = self.visit(value)
|
| 448 |
+
if value is None:
|
| 449 |
+
continue
|
| 450 |
+
elif not isinstance(value, AST):
|
| 451 |
+
new_values.extend(value)
|
| 452 |
+
continue
|
| 453 |
+
new_values.append(value)
|
| 454 |
+
old_value[:] = new_values
|
| 455 |
+
elif isinstance(old_value, AST):
|
| 456 |
+
new_node = self.visit(old_value)
|
| 457 |
+
if new_node is None:
|
| 458 |
+
delattr(node, field)
|
| 459 |
+
else:
|
| 460 |
+
setattr(node, field, new_node)
|
| 461 |
+
return node
|
| 462 |
+
|
| 463 |
+
|
| 464 |
+
# The following code is for backward compatibility.
|
| 465 |
+
# It will be removed in future.
|
| 466 |
+
|
| 467 |
+
def _getter(self):
|
| 468 |
+
return self.value
|
| 469 |
+
|
| 470 |
+
def _setter(self, value):
|
| 471 |
+
self.value = value
|
| 472 |
+
|
| 473 |
+
Constant.n = property(_getter, _setter)
|
| 474 |
+
Constant.s = property(_getter, _setter)
|
| 475 |
+
|
| 476 |
+
class _ABC(type):
|
| 477 |
+
|
| 478 |
+
def __instancecheck__(cls, inst):
|
| 479 |
+
if not isinstance(inst, Constant):
|
| 480 |
+
return False
|
| 481 |
+
if cls in _const_types:
|
| 482 |
+
try:
|
| 483 |
+
value = inst.value
|
| 484 |
+
except AttributeError:
|
| 485 |
+
return False
|
| 486 |
+
else:
|
| 487 |
+
return (
|
| 488 |
+
isinstance(value, _const_types[cls]) and
|
| 489 |
+
not isinstance(value, _const_types_not.get(cls, ()))
|
| 490 |
+
)
|
| 491 |
+
return type.__instancecheck__(cls, inst)
|
| 492 |
+
|
| 493 |
+
def _new(cls, *args, **kwargs):
|
| 494 |
+
for key in kwargs:
|
| 495 |
+
if key not in cls._fields:
|
| 496 |
+
# arbitrary keyword arguments are accepted
|
| 497 |
+
continue
|
| 498 |
+
pos = cls._fields.index(key)
|
| 499 |
+
if pos < len(args):
|
| 500 |
+
raise TypeError(f"{cls.__name__} got multiple values for argument {key!r}")
|
| 501 |
+
if cls in _const_types:
|
| 502 |
+
return Constant(*args, **kwargs)
|
| 503 |
+
return Constant.__new__(cls, *args, **kwargs)
|
| 504 |
+
|
| 505 |
+
class Num(Constant, metaclass=_ABC):
|
| 506 |
+
_fields = ('n',)
|
| 507 |
+
__new__ = _new
|
| 508 |
+
|
| 509 |
+
class Str(Constant, metaclass=_ABC):
|
| 510 |
+
_fields = ('s',)
|
| 511 |
+
__new__ = _new
|
| 512 |
+
|
| 513 |
+
class Bytes(Constant, metaclass=_ABC):
|
| 514 |
+
_fields = ('s',)
|
| 515 |
+
__new__ = _new
|
| 516 |
+
|
| 517 |
+
class NameConstant(Constant, metaclass=_ABC):
|
| 518 |
+
__new__ = _new
|
| 519 |
+
|
| 520 |
+
class Ellipsis(Constant, metaclass=_ABC):
|
| 521 |
+
_fields = ()
|
| 522 |
+
|
| 523 |
+
def __new__(cls, *args, **kwargs):
|
| 524 |
+
if cls is Ellipsis:
|
| 525 |
+
return Constant(..., *args, **kwargs)
|
| 526 |
+
return Constant.__new__(cls, *args, **kwargs)
|
| 527 |
+
|
| 528 |
+
_const_types = {
|
| 529 |
+
Num: (int, float, complex),
|
| 530 |
+
Str: (str,),
|
| 531 |
+
Bytes: (bytes,),
|
| 532 |
+
NameConstant: (type(None), bool),
|
| 533 |
+
Ellipsis: (type(...),),
|
| 534 |
+
}
|
| 535 |
+
_const_types_not = {
|
| 536 |
+
Num: (bool,),
|
| 537 |
+
}
|
| 538 |
+
_const_node_type_names = {
|
| 539 |
+
bool: 'NameConstant', # should be before int
|
| 540 |
+
type(None): 'NameConstant',
|
| 541 |
+
int: 'Num',
|
| 542 |
+
float: 'Num',
|
| 543 |
+
complex: 'Num',
|
| 544 |
+
str: 'Str',
|
| 545 |
+
bytes: 'Bytes',
|
| 546 |
+
type(...): 'Ellipsis',
|
| 547 |
+
}
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/asynchat.py
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- Mode: Python; tab-width: 4 -*-
|
| 2 |
+
# Id: asynchat.py,v 2.26 2000/09/07 22:29:26 rushing Exp
|
| 3 |
+
# Author: Sam Rushing <rushing@nightmare.com>
|
| 4 |
+
|
| 5 |
+
# ======================================================================
|
| 6 |
+
# Copyright 1996 by Sam Rushing
|
| 7 |
+
#
|
| 8 |
+
# All Rights Reserved
|
| 9 |
+
#
|
| 10 |
+
# Permission to use, copy, modify, and distribute this software and
|
| 11 |
+
# its documentation for any purpose and without fee is hereby
|
| 12 |
+
# granted, provided that the above copyright notice appear in all
|
| 13 |
+
# copies and that both that copyright notice and this permission
|
| 14 |
+
# notice appear in supporting documentation, and that the name of Sam
|
| 15 |
+
# Rushing not be used in advertising or publicity pertaining to
|
| 16 |
+
# distribution of the software without specific, written prior
|
| 17 |
+
# permission.
|
| 18 |
+
#
|
| 19 |
+
# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
| 20 |
+
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
| 21 |
+
# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
| 22 |
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
| 23 |
+
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
| 24 |
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
| 25 |
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
| 26 |
+
# ======================================================================
|
| 27 |
+
|
| 28 |
+
r"""A class supporting chat-style (command/response) protocols.
|
| 29 |
+
|
| 30 |
+
This class adds support for 'chat' style protocols - where one side
|
| 31 |
+
sends a 'command', and the other sends a response (examples would be
|
| 32 |
+
the common internet protocols - smtp, nntp, ftp, etc..).
|
| 33 |
+
|
| 34 |
+
The handle_read() method looks at the input stream for the current
|
| 35 |
+
'terminator' (usually '\r\n' for single-line responses, '\r\n.\r\n'
|
| 36 |
+
for multi-line output), calling self.found_terminator() on its
|
| 37 |
+
receipt.
|
| 38 |
+
|
| 39 |
+
for example:
|
| 40 |
+
Say you build an async nntp client using this class. At the start
|
| 41 |
+
of the connection, you'll have self.terminator set to '\r\n', in
|
| 42 |
+
order to process the single-line greeting. Just before issuing a
|
| 43 |
+
'LIST' command you'll set it to '\r\n.\r\n'. The output of the LIST
|
| 44 |
+
command will be accumulated (using your own 'collect_incoming_data'
|
| 45 |
+
method) up to the terminator, and then control will be returned to
|
| 46 |
+
you - by calling your self.found_terminator() method.
|
| 47 |
+
"""
|
| 48 |
+
import asyncore
|
| 49 |
+
from collections import deque
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
class async_chat(asyncore.dispatcher):
|
| 53 |
+
"""This is an abstract class. You must derive from this class, and add
|
| 54 |
+
the two methods collect_incoming_data() and found_terminator()"""
|
| 55 |
+
|
| 56 |
+
# these are overridable defaults
|
| 57 |
+
|
| 58 |
+
ac_in_buffer_size = 65536
|
| 59 |
+
ac_out_buffer_size = 65536
|
| 60 |
+
|
| 61 |
+
# we don't want to enable the use of encoding by default, because that is a
|
| 62 |
+
# sign of an application bug that we don't want to pass silently
|
| 63 |
+
|
| 64 |
+
use_encoding = 0
|
| 65 |
+
encoding = 'latin-1'
|
| 66 |
+
|
| 67 |
+
def __init__(self, sock=None, map=None):
|
| 68 |
+
# for string terminator matching
|
| 69 |
+
self.ac_in_buffer = b''
|
| 70 |
+
|
| 71 |
+
# we use a list here rather than io.BytesIO for a few reasons...
|
| 72 |
+
# del lst[:] is faster than bio.truncate(0)
|
| 73 |
+
# lst = [] is faster than bio.truncate(0)
|
| 74 |
+
self.incoming = []
|
| 75 |
+
|
| 76 |
+
# we toss the use of the "simple producer" and replace it with
|
| 77 |
+
# a pure deque, which the original fifo was a wrapping of
|
| 78 |
+
self.producer_fifo = deque()
|
| 79 |
+
asyncore.dispatcher.__init__(self, sock, map)
|
| 80 |
+
|
| 81 |
+
def collect_incoming_data(self, data):
|
| 82 |
+
raise NotImplementedError("must be implemented in subclass")
|
| 83 |
+
|
| 84 |
+
def _collect_incoming_data(self, data):
|
| 85 |
+
self.incoming.append(data)
|
| 86 |
+
|
| 87 |
+
def _get_data(self):
|
| 88 |
+
d = b''.join(self.incoming)
|
| 89 |
+
del self.incoming[:]
|
| 90 |
+
return d
|
| 91 |
+
|
| 92 |
+
def found_terminator(self):
|
| 93 |
+
raise NotImplementedError("must be implemented in subclass")
|
| 94 |
+
|
| 95 |
+
def set_terminator(self, term):
|
| 96 |
+
"""Set the input delimiter.
|
| 97 |
+
|
| 98 |
+
Can be a fixed string of any length, an integer, or None.
|
| 99 |
+
"""
|
| 100 |
+
if isinstance(term, str) and self.use_encoding:
|
| 101 |
+
term = bytes(term, self.encoding)
|
| 102 |
+
elif isinstance(term, int) and term < 0:
|
| 103 |
+
raise ValueError('the number of received bytes must be positive')
|
| 104 |
+
self.terminator = term
|
| 105 |
+
|
| 106 |
+
def get_terminator(self):
|
| 107 |
+
return self.terminator
|
| 108 |
+
|
| 109 |
+
# grab some more data from the socket,
|
| 110 |
+
# throw it to the collector method,
|
| 111 |
+
# check for the terminator,
|
| 112 |
+
# if found, transition to the next state.
|
| 113 |
+
|
| 114 |
+
def handle_read(self):
|
| 115 |
+
|
| 116 |
+
try:
|
| 117 |
+
data = self.recv(self.ac_in_buffer_size)
|
| 118 |
+
except BlockingIOError:
|
| 119 |
+
return
|
| 120 |
+
except OSError as why:
|
| 121 |
+
self.handle_error()
|
| 122 |
+
return
|
| 123 |
+
|
| 124 |
+
if isinstance(data, str) and self.use_encoding:
|
| 125 |
+
data = bytes(str, self.encoding)
|
| 126 |
+
self.ac_in_buffer = self.ac_in_buffer + data
|
| 127 |
+
|
| 128 |
+
# Continue to search for self.terminator in self.ac_in_buffer,
|
| 129 |
+
# while calling self.collect_incoming_data. The while loop
|
| 130 |
+
# is necessary because we might read several data+terminator
|
| 131 |
+
# combos with a single recv(4096).
|
| 132 |
+
|
| 133 |
+
while self.ac_in_buffer:
|
| 134 |
+
lb = len(self.ac_in_buffer)
|
| 135 |
+
terminator = self.get_terminator()
|
| 136 |
+
if not terminator:
|
| 137 |
+
# no terminator, collect it all
|
| 138 |
+
self.collect_incoming_data(self.ac_in_buffer)
|
| 139 |
+
self.ac_in_buffer = b''
|
| 140 |
+
elif isinstance(terminator, int):
|
| 141 |
+
# numeric terminator
|
| 142 |
+
n = terminator
|
| 143 |
+
if lb < n:
|
| 144 |
+
self.collect_incoming_data(self.ac_in_buffer)
|
| 145 |
+
self.ac_in_buffer = b''
|
| 146 |
+
self.terminator = self.terminator - lb
|
| 147 |
+
else:
|
| 148 |
+
self.collect_incoming_data(self.ac_in_buffer[:n])
|
| 149 |
+
self.ac_in_buffer = self.ac_in_buffer[n:]
|
| 150 |
+
self.terminator = 0
|
| 151 |
+
self.found_terminator()
|
| 152 |
+
else:
|
| 153 |
+
# 3 cases:
|
| 154 |
+
# 1) end of buffer matches terminator exactly:
|
| 155 |
+
# collect data, transition
|
| 156 |
+
# 2) end of buffer matches some prefix:
|
| 157 |
+
# collect data to the prefix
|
| 158 |
+
# 3) end of buffer does not match any prefix:
|
| 159 |
+
# collect data
|
| 160 |
+
terminator_len = len(terminator)
|
| 161 |
+
index = self.ac_in_buffer.find(terminator)
|
| 162 |
+
if index != -1:
|
| 163 |
+
# we found the terminator
|
| 164 |
+
if index > 0:
|
| 165 |
+
# don't bother reporting the empty string
|
| 166 |
+
# (source of subtle bugs)
|
| 167 |
+
self.collect_incoming_data(self.ac_in_buffer[:index])
|
| 168 |
+
self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:]
|
| 169 |
+
# This does the Right Thing if the terminator
|
| 170 |
+
# is changed here.
|
| 171 |
+
self.found_terminator()
|
| 172 |
+
else:
|
| 173 |
+
# check for a prefix of the terminator
|
| 174 |
+
index = find_prefix_at_end(self.ac_in_buffer, terminator)
|
| 175 |
+
if index:
|
| 176 |
+
if index != lb:
|
| 177 |
+
# we found a prefix, collect up to the prefix
|
| 178 |
+
self.collect_incoming_data(self.ac_in_buffer[:-index])
|
| 179 |
+
self.ac_in_buffer = self.ac_in_buffer[-index:]
|
| 180 |
+
break
|
| 181 |
+
else:
|
| 182 |
+
# no prefix, collect it all
|
| 183 |
+
self.collect_incoming_data(self.ac_in_buffer)
|
| 184 |
+
self.ac_in_buffer = b''
|
| 185 |
+
|
| 186 |
+
def handle_write(self):
|
| 187 |
+
self.initiate_send()
|
| 188 |
+
|
| 189 |
+
def handle_close(self):
|
| 190 |
+
self.close()
|
| 191 |
+
|
| 192 |
+
def push(self, data):
|
| 193 |
+
if not isinstance(data, (bytes, bytearray, memoryview)):
|
| 194 |
+
raise TypeError('data argument must be byte-ish (%r)',
|
| 195 |
+
type(data))
|
| 196 |
+
sabs = self.ac_out_buffer_size
|
| 197 |
+
if len(data) > sabs:
|
| 198 |
+
for i in range(0, len(data), sabs):
|
| 199 |
+
self.producer_fifo.append(data[i:i+sabs])
|
| 200 |
+
else:
|
| 201 |
+
self.producer_fifo.append(data)
|
| 202 |
+
self.initiate_send()
|
| 203 |
+
|
| 204 |
+
def push_with_producer(self, producer):
|
| 205 |
+
self.producer_fifo.append(producer)
|
| 206 |
+
self.initiate_send()
|
| 207 |
+
|
| 208 |
+
def readable(self):
|
| 209 |
+
"predicate for inclusion in the readable for select()"
|
| 210 |
+
# cannot use the old predicate, it violates the claim of the
|
| 211 |
+
# set_terminator method.
|
| 212 |
+
|
| 213 |
+
# return (len(self.ac_in_buffer) <= self.ac_in_buffer_size)
|
| 214 |
+
return 1
|
| 215 |
+
|
| 216 |
+
def writable(self):
|
| 217 |
+
"predicate for inclusion in the writable for select()"
|
| 218 |
+
return self.producer_fifo or (not self.connected)
|
| 219 |
+
|
| 220 |
+
def close_when_done(self):
|
| 221 |
+
"automatically close this channel once the outgoing queue is empty"
|
| 222 |
+
self.producer_fifo.append(None)
|
| 223 |
+
|
| 224 |
+
def initiate_send(self):
|
| 225 |
+
while self.producer_fifo and self.connected:
|
| 226 |
+
first = self.producer_fifo[0]
|
| 227 |
+
# handle empty string/buffer or None entry
|
| 228 |
+
if not first:
|
| 229 |
+
del self.producer_fifo[0]
|
| 230 |
+
if first is None:
|
| 231 |
+
self.handle_close()
|
| 232 |
+
return
|
| 233 |
+
|
| 234 |
+
# handle classic producer behavior
|
| 235 |
+
obs = self.ac_out_buffer_size
|
| 236 |
+
try:
|
| 237 |
+
data = first[:obs]
|
| 238 |
+
except TypeError:
|
| 239 |
+
data = first.more()
|
| 240 |
+
if data:
|
| 241 |
+
self.producer_fifo.appendleft(data)
|
| 242 |
+
else:
|
| 243 |
+
del self.producer_fifo[0]
|
| 244 |
+
continue
|
| 245 |
+
|
| 246 |
+
if isinstance(data, str) and self.use_encoding:
|
| 247 |
+
data = bytes(data, self.encoding)
|
| 248 |
+
|
| 249 |
+
# send the data
|
| 250 |
+
try:
|
| 251 |
+
num_sent = self.send(data)
|
| 252 |
+
except OSError:
|
| 253 |
+
self.handle_error()
|
| 254 |
+
return
|
| 255 |
+
|
| 256 |
+
if num_sent:
|
| 257 |
+
if num_sent < len(data) or obs < len(first):
|
| 258 |
+
self.producer_fifo[0] = first[num_sent:]
|
| 259 |
+
else:
|
| 260 |
+
del self.producer_fifo[0]
|
| 261 |
+
# we tried to send some actual data
|
| 262 |
+
return
|
| 263 |
+
|
| 264 |
+
def discard_buffers(self):
|
| 265 |
+
# Emergencies only!
|
| 266 |
+
self.ac_in_buffer = b''
|
| 267 |
+
del self.incoming[:]
|
| 268 |
+
self.producer_fifo.clear()
|
| 269 |
+
|
| 270 |
+
|
| 271 |
+
class simple_producer:
|
| 272 |
+
|
| 273 |
+
def __init__(self, data, buffer_size=512):
|
| 274 |
+
self.data = data
|
| 275 |
+
self.buffer_size = buffer_size
|
| 276 |
+
|
| 277 |
+
def more(self):
|
| 278 |
+
if len(self.data) > self.buffer_size:
|
| 279 |
+
result = self.data[:self.buffer_size]
|
| 280 |
+
self.data = self.data[self.buffer_size:]
|
| 281 |
+
return result
|
| 282 |
+
else:
|
| 283 |
+
result = self.data
|
| 284 |
+
self.data = b''
|
| 285 |
+
return result
|
| 286 |
+
|
| 287 |
+
|
| 288 |
+
# Given 'haystack', see if any prefix of 'needle' is at its end. This
|
| 289 |
+
# assumes an exact match has already been checked. Return the number of
|
| 290 |
+
# characters matched.
|
| 291 |
+
# for example:
|
| 292 |
+
# f_p_a_e("qwerty\r", "\r\n") => 1
|
| 293 |
+
# f_p_a_e("qwertydkjf", "\r\n") => 0
|
| 294 |
+
# f_p_a_e("qwerty\r\n", "\r\n") => <undefined>
|
| 295 |
+
|
| 296 |
+
# this could maybe be made faster with a computed regex?
|
| 297 |
+
# [answer: no; circa Python-2.0, Jan 2001]
|
| 298 |
+
# new python: 28961/s
|
| 299 |
+
# old python: 18307/s
|
| 300 |
+
# re: 12820/s
|
| 301 |
+
# regex: 14035/s
|
| 302 |
+
|
| 303 |
+
def find_prefix_at_end(haystack, needle):
|
| 304 |
+
l = len(needle) - 1
|
| 305 |
+
while l and not haystack.endswith(needle[:l]):
|
| 306 |
+
l -= 1
|
| 307 |
+
return l
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/base64.py
ADDED
|
@@ -0,0 +1,595 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#! /usr/bin/env python3
|
| 2 |
+
|
| 3 |
+
"""Base16, Base32, Base64 (RFC 3548), Base85 and Ascii85 data encodings"""
|
| 4 |
+
|
| 5 |
+
# Modified 04-Oct-1995 by Jack Jansen to use binascii module
|
| 6 |
+
# Modified 30-Dec-2003 by Barry Warsaw to add full RFC 3548 support
|
| 7 |
+
# Modified 22-May-2007 by Guido van Rossum to use bytes everywhere
|
| 8 |
+
|
| 9 |
+
import re
|
| 10 |
+
import struct
|
| 11 |
+
import binascii
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
__all__ = [
|
| 15 |
+
# Legacy interface exports traditional RFC 2045 Base64 encodings
|
| 16 |
+
'encode', 'decode', 'encodebytes', 'decodebytes',
|
| 17 |
+
# Generalized interface for other encodings
|
| 18 |
+
'b64encode', 'b64decode', 'b32encode', 'b32decode',
|
| 19 |
+
'b16encode', 'b16decode',
|
| 20 |
+
# Base85 and Ascii85 encodings
|
| 21 |
+
'b85encode', 'b85decode', 'a85encode', 'a85decode',
|
| 22 |
+
# Standard Base64 encoding
|
| 23 |
+
'standard_b64encode', 'standard_b64decode',
|
| 24 |
+
# Some common Base64 alternatives. As referenced by RFC 3458, see thread
|
| 25 |
+
# starting at:
|
| 26 |
+
#
|
| 27 |
+
# http://zgp.org/pipermail/p2p-hackers/2001-September/000316.html
|
| 28 |
+
'urlsafe_b64encode', 'urlsafe_b64decode',
|
| 29 |
+
]
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
bytes_types = (bytes, bytearray) # Types acceptable as binary data
|
| 33 |
+
|
| 34 |
+
def _bytes_from_decode_data(s):
|
| 35 |
+
if isinstance(s, str):
|
| 36 |
+
try:
|
| 37 |
+
return s.encode('ascii')
|
| 38 |
+
except UnicodeEncodeError:
|
| 39 |
+
raise ValueError('string argument should contain only ASCII characters')
|
| 40 |
+
if isinstance(s, bytes_types):
|
| 41 |
+
return s
|
| 42 |
+
try:
|
| 43 |
+
return memoryview(s).tobytes()
|
| 44 |
+
except TypeError:
|
| 45 |
+
raise TypeError("argument should be a bytes-like object or ASCII "
|
| 46 |
+
"string, not %r" % s.__class__.__name__) from None
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
# Base64 encoding/decoding uses binascii
|
| 50 |
+
|
| 51 |
+
def b64encode(s, altchars=None):
|
| 52 |
+
"""Encode the bytes-like object s using Base64 and return a bytes object.
|
| 53 |
+
|
| 54 |
+
Optional altchars should be a byte string of length 2 which specifies an
|
| 55 |
+
alternative alphabet for the '+' and '/' characters. This allows an
|
| 56 |
+
application to e.g. generate url or filesystem safe Base64 strings.
|
| 57 |
+
"""
|
| 58 |
+
encoded = binascii.b2a_base64(s, newline=False)
|
| 59 |
+
if altchars is not None:
|
| 60 |
+
assert len(altchars) == 2, repr(altchars)
|
| 61 |
+
return encoded.translate(bytes.maketrans(b'+/', altchars))
|
| 62 |
+
return encoded
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def b64decode(s, altchars=None, validate=False):
|
| 66 |
+
"""Decode the Base64 encoded bytes-like object or ASCII string s.
|
| 67 |
+
|
| 68 |
+
Optional altchars must be a bytes-like object or ASCII string of length 2
|
| 69 |
+
which specifies the alternative alphabet used instead of the '+' and '/'
|
| 70 |
+
characters.
|
| 71 |
+
|
| 72 |
+
The result is returned as a bytes object. A binascii.Error is raised if
|
| 73 |
+
s is incorrectly padded.
|
| 74 |
+
|
| 75 |
+
If validate is False (the default), characters that are neither in the
|
| 76 |
+
normal base-64 alphabet nor the alternative alphabet are discarded prior
|
| 77 |
+
to the padding check. If validate is True, these non-alphabet characters
|
| 78 |
+
in the input result in a binascii.Error.
|
| 79 |
+
"""
|
| 80 |
+
s = _bytes_from_decode_data(s)
|
| 81 |
+
if altchars is not None:
|
| 82 |
+
altchars = _bytes_from_decode_data(altchars)
|
| 83 |
+
assert len(altchars) == 2, repr(altchars)
|
| 84 |
+
s = s.translate(bytes.maketrans(altchars, b'+/'))
|
| 85 |
+
if validate and not re.fullmatch(b'[A-Za-z0-9+/]*={0,2}', s):
|
| 86 |
+
raise binascii.Error('Non-base64 digit found')
|
| 87 |
+
return binascii.a2b_base64(s)
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def standard_b64encode(s):
|
| 91 |
+
"""Encode bytes-like object s using the standard Base64 alphabet.
|
| 92 |
+
|
| 93 |
+
The result is returned as a bytes object.
|
| 94 |
+
"""
|
| 95 |
+
return b64encode(s)
|
| 96 |
+
|
| 97 |
+
def standard_b64decode(s):
|
| 98 |
+
"""Decode bytes encoded with the standard Base64 alphabet.
|
| 99 |
+
|
| 100 |
+
Argument s is a bytes-like object or ASCII string to decode. The result
|
| 101 |
+
is returned as a bytes object. A binascii.Error is raised if the input
|
| 102 |
+
is incorrectly padded. Characters that are not in the standard alphabet
|
| 103 |
+
are discarded prior to the padding check.
|
| 104 |
+
"""
|
| 105 |
+
return b64decode(s)
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
_urlsafe_encode_translation = bytes.maketrans(b'+/', b'-_')
|
| 109 |
+
_urlsafe_decode_translation = bytes.maketrans(b'-_', b'+/')
|
| 110 |
+
|
| 111 |
+
def urlsafe_b64encode(s):
|
| 112 |
+
"""Encode bytes using the URL- and filesystem-safe Base64 alphabet.
|
| 113 |
+
|
| 114 |
+
Argument s is a bytes-like object to encode. The result is returned as a
|
| 115 |
+
bytes object. The alphabet uses '-' instead of '+' and '_' instead of
|
| 116 |
+
'/'.
|
| 117 |
+
"""
|
| 118 |
+
return b64encode(s).translate(_urlsafe_encode_translation)
|
| 119 |
+
|
| 120 |
+
def urlsafe_b64decode(s):
|
| 121 |
+
"""Decode bytes using the URL- and filesystem-safe Base64 alphabet.
|
| 122 |
+
|
| 123 |
+
Argument s is a bytes-like object or ASCII string to decode. The result
|
| 124 |
+
is returned as a bytes object. A binascii.Error is raised if the input
|
| 125 |
+
is incorrectly padded. Characters that are not in the URL-safe base-64
|
| 126 |
+
alphabet, and are not a plus '+' or slash '/', are discarded prior to the
|
| 127 |
+
padding check.
|
| 128 |
+
|
| 129 |
+
The alphabet uses '-' instead of '+' and '_' instead of '/'.
|
| 130 |
+
"""
|
| 131 |
+
s = _bytes_from_decode_data(s)
|
| 132 |
+
s = s.translate(_urlsafe_decode_translation)
|
| 133 |
+
return b64decode(s)
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
# Base32 encoding/decoding must be done in Python
|
| 138 |
+
_b32alphabet = b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
|
| 139 |
+
_b32tab2 = None
|
| 140 |
+
_b32rev = None
|
| 141 |
+
|
| 142 |
+
def b32encode(s):
|
| 143 |
+
"""Encode the bytes-like object s using Base32 and return a bytes object.
|
| 144 |
+
"""
|
| 145 |
+
global _b32tab2
|
| 146 |
+
# Delay the initialization of the table to not waste memory
|
| 147 |
+
# if the function is never called
|
| 148 |
+
if _b32tab2 is None:
|
| 149 |
+
b32tab = [bytes((i,)) for i in _b32alphabet]
|
| 150 |
+
_b32tab2 = [a + b for a in b32tab for b in b32tab]
|
| 151 |
+
b32tab = None
|
| 152 |
+
|
| 153 |
+
if not isinstance(s, bytes_types):
|
| 154 |
+
s = memoryview(s).tobytes()
|
| 155 |
+
leftover = len(s) % 5
|
| 156 |
+
# Pad the last quantum with zero bits if necessary
|
| 157 |
+
if leftover:
|
| 158 |
+
s = s + b'\0' * (5 - leftover) # Don't use += !
|
| 159 |
+
encoded = bytearray()
|
| 160 |
+
from_bytes = int.from_bytes
|
| 161 |
+
b32tab2 = _b32tab2
|
| 162 |
+
for i in range(0, len(s), 5):
|
| 163 |
+
c = from_bytes(s[i: i + 5], 'big')
|
| 164 |
+
encoded += (b32tab2[c >> 30] + # bits 1 - 10
|
| 165 |
+
b32tab2[(c >> 20) & 0x3ff] + # bits 11 - 20
|
| 166 |
+
b32tab2[(c >> 10) & 0x3ff] + # bits 21 - 30
|
| 167 |
+
b32tab2[c & 0x3ff] # bits 31 - 40
|
| 168 |
+
)
|
| 169 |
+
# Adjust for any leftover partial quanta
|
| 170 |
+
if leftover == 1:
|
| 171 |
+
encoded[-6:] = b'======'
|
| 172 |
+
elif leftover == 2:
|
| 173 |
+
encoded[-4:] = b'===='
|
| 174 |
+
elif leftover == 3:
|
| 175 |
+
encoded[-3:] = b'==='
|
| 176 |
+
elif leftover == 4:
|
| 177 |
+
encoded[-1:] = b'='
|
| 178 |
+
return bytes(encoded)
|
| 179 |
+
|
| 180 |
+
def b32decode(s, casefold=False, map01=None):
|
| 181 |
+
"""Decode the Base32 encoded bytes-like object or ASCII string s.
|
| 182 |
+
|
| 183 |
+
Optional casefold is a flag specifying whether a lowercase alphabet is
|
| 184 |
+
acceptable as input. For security purposes, the default is False.
|
| 185 |
+
|
| 186 |
+
RFC 3548 allows for optional mapping of the digit 0 (zero) to the
|
| 187 |
+
letter O (oh), and for optional mapping of the digit 1 (one) to
|
| 188 |
+
either the letter I (eye) or letter L (el). The optional argument
|
| 189 |
+
map01 when not None, specifies which letter the digit 1 should be
|
| 190 |
+
mapped to (when map01 is not None, the digit 0 is always mapped to
|
| 191 |
+
the letter O). For security purposes the default is None, so that
|
| 192 |
+
0 and 1 are not allowed in the input.
|
| 193 |
+
|
| 194 |
+
The result is returned as a bytes object. A binascii.Error is raised if
|
| 195 |
+
the input is incorrectly padded or if there are non-alphabet
|
| 196 |
+
characters present in the input.
|
| 197 |
+
"""
|
| 198 |
+
global _b32rev
|
| 199 |
+
# Delay the initialization of the table to not waste memory
|
| 200 |
+
# if the function is never called
|
| 201 |
+
if _b32rev is None:
|
| 202 |
+
_b32rev = {v: k for k, v in enumerate(_b32alphabet)}
|
| 203 |
+
s = _bytes_from_decode_data(s)
|
| 204 |
+
if len(s) % 8:
|
| 205 |
+
raise binascii.Error('Incorrect padding')
|
| 206 |
+
# Handle section 2.4 zero and one mapping. The flag map01 will be either
|
| 207 |
+
# False, or the character to map the digit 1 (one) to. It should be
|
| 208 |
+
# either L (el) or I (eye).
|
| 209 |
+
if map01 is not None:
|
| 210 |
+
map01 = _bytes_from_decode_data(map01)
|
| 211 |
+
assert len(map01) == 1, repr(map01)
|
| 212 |
+
s = s.translate(bytes.maketrans(b'01', b'O' + map01))
|
| 213 |
+
if casefold:
|
| 214 |
+
s = s.upper()
|
| 215 |
+
# Strip off pad characters from the right. We need to count the pad
|
| 216 |
+
# characters because this will tell us how many null bytes to remove from
|
| 217 |
+
# the end of the decoded string.
|
| 218 |
+
l = len(s)
|
| 219 |
+
s = s.rstrip(b'=')
|
| 220 |
+
padchars = l - len(s)
|
| 221 |
+
# Now decode the full quanta
|
| 222 |
+
decoded = bytearray()
|
| 223 |
+
b32rev = _b32rev
|
| 224 |
+
for i in range(0, len(s), 8):
|
| 225 |
+
quanta = s[i: i + 8]
|
| 226 |
+
acc = 0
|
| 227 |
+
try:
|
| 228 |
+
for c in quanta:
|
| 229 |
+
acc = (acc << 5) + b32rev[c]
|
| 230 |
+
except KeyError:
|
| 231 |
+
raise binascii.Error('Non-base32 digit found') from None
|
| 232 |
+
decoded += acc.to_bytes(5, 'big')
|
| 233 |
+
# Process the last, partial quanta
|
| 234 |
+
if l % 8 or padchars not in {0, 1, 3, 4, 6}:
|
| 235 |
+
raise binascii.Error('Incorrect padding')
|
| 236 |
+
if padchars and decoded:
|
| 237 |
+
acc <<= 5 * padchars
|
| 238 |
+
last = acc.to_bytes(5, 'big')
|
| 239 |
+
leftover = (43 - 5 * padchars) // 8 # 1: 4, 3: 3, 4: 2, 6: 1
|
| 240 |
+
decoded[-5:] = last[:leftover]
|
| 241 |
+
return bytes(decoded)
|
| 242 |
+
|
| 243 |
+
|
| 244 |
+
# RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns
|
| 245 |
+
# lowercase. The RFC also recommends against accepting input case
|
| 246 |
+
# insensitively.
|
| 247 |
+
def b16encode(s):
|
| 248 |
+
"""Encode the bytes-like object s using Base16 and return a bytes object.
|
| 249 |
+
"""
|
| 250 |
+
return binascii.hexlify(s).upper()
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
def b16decode(s, casefold=False):
|
| 254 |
+
"""Decode the Base16 encoded bytes-like object or ASCII string s.
|
| 255 |
+
|
| 256 |
+
Optional casefold is a flag specifying whether a lowercase alphabet is
|
| 257 |
+
acceptable as input. For security purposes, the default is False.
|
| 258 |
+
|
| 259 |
+
The result is returned as a bytes object. A binascii.Error is raised if
|
| 260 |
+
s is incorrectly padded or if there are non-alphabet characters present
|
| 261 |
+
in the input.
|
| 262 |
+
"""
|
| 263 |
+
s = _bytes_from_decode_data(s)
|
| 264 |
+
if casefold:
|
| 265 |
+
s = s.upper()
|
| 266 |
+
if re.search(b'[^0-9A-F]', s):
|
| 267 |
+
raise binascii.Error('Non-base16 digit found')
|
| 268 |
+
return binascii.unhexlify(s)
|
| 269 |
+
|
| 270 |
+
#
|
| 271 |
+
# Ascii85 encoding/decoding
|
| 272 |
+
#
|
| 273 |
+
|
| 274 |
+
_a85chars = None
|
| 275 |
+
_a85chars2 = None
|
| 276 |
+
_A85START = b"<~"
|
| 277 |
+
_A85END = b"~>"
|
| 278 |
+
|
| 279 |
+
def _85encode(b, chars, chars2, pad=False, foldnuls=False, foldspaces=False):
|
| 280 |
+
# Helper function for a85encode and b85encode
|
| 281 |
+
if not isinstance(b, bytes_types):
|
| 282 |
+
b = memoryview(b).tobytes()
|
| 283 |
+
|
| 284 |
+
padding = (-len(b)) % 4
|
| 285 |
+
if padding:
|
| 286 |
+
b = b + b'\0' * padding
|
| 287 |
+
words = struct.Struct('!%dI' % (len(b) // 4)).unpack(b)
|
| 288 |
+
|
| 289 |
+
chunks = [b'z' if foldnuls and not word else
|
| 290 |
+
b'y' if foldspaces and word == 0x20202020 else
|
| 291 |
+
(chars2[word // 614125] +
|
| 292 |
+
chars2[word // 85 % 7225] +
|
| 293 |
+
chars[word % 85])
|
| 294 |
+
for word in words]
|
| 295 |
+
|
| 296 |
+
if padding and not pad:
|
| 297 |
+
if chunks[-1] == b'z':
|
| 298 |
+
chunks[-1] = chars[0] * 5
|
| 299 |
+
chunks[-1] = chunks[-1][:-padding]
|
| 300 |
+
|
| 301 |
+
return b''.join(chunks)
|
| 302 |
+
|
| 303 |
+
def a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False):
|
| 304 |
+
"""Encode bytes-like object b using Ascii85 and return a bytes object.
|
| 305 |
+
|
| 306 |
+
foldspaces is an optional flag that uses the special short sequence 'y'
|
| 307 |
+
instead of 4 consecutive spaces (ASCII 0x20) as supported by 'btoa'. This
|
| 308 |
+
feature is not supported by the "standard" Adobe encoding.
|
| 309 |
+
|
| 310 |
+
wrapcol controls whether the output should have newline (b'\\n') characters
|
| 311 |
+
added to it. If this is non-zero, each output line will be at most this
|
| 312 |
+
many characters long.
|
| 313 |
+
|
| 314 |
+
pad controls whether the input is padded to a multiple of 4 before
|
| 315 |
+
encoding. Note that the btoa implementation always pads.
|
| 316 |
+
|
| 317 |
+
adobe controls whether the encoded byte sequence is framed with <~ and ~>,
|
| 318 |
+
which is used by the Adobe implementation.
|
| 319 |
+
"""
|
| 320 |
+
global _a85chars, _a85chars2
|
| 321 |
+
# Delay the initialization of tables to not waste memory
|
| 322 |
+
# if the function is never called
|
| 323 |
+
if _a85chars2 is None:
|
| 324 |
+
_a85chars = [bytes((i,)) for i in range(33, 118)]
|
| 325 |
+
_a85chars2 = [(a + b) for a in _a85chars for b in _a85chars]
|
| 326 |
+
|
| 327 |
+
result = _85encode(b, _a85chars, _a85chars2, pad, True, foldspaces)
|
| 328 |
+
|
| 329 |
+
if adobe:
|
| 330 |
+
result = _A85START + result
|
| 331 |
+
if wrapcol:
|
| 332 |
+
wrapcol = max(2 if adobe else 1, wrapcol)
|
| 333 |
+
chunks = [result[i: i + wrapcol]
|
| 334 |
+
for i in range(0, len(result), wrapcol)]
|
| 335 |
+
if adobe:
|
| 336 |
+
if len(chunks[-1]) + 2 > wrapcol:
|
| 337 |
+
chunks.append(b'')
|
| 338 |
+
result = b'\n'.join(chunks)
|
| 339 |
+
if adobe:
|
| 340 |
+
result += _A85END
|
| 341 |
+
|
| 342 |
+
return result
|
| 343 |
+
|
| 344 |
+
def a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v'):
|
| 345 |
+
"""Decode the Ascii85 encoded bytes-like object or ASCII string b.
|
| 346 |
+
|
| 347 |
+
foldspaces is a flag that specifies whether the 'y' short sequence should be
|
| 348 |
+
accepted as shorthand for 4 consecutive spaces (ASCII 0x20). This feature is
|
| 349 |
+
not supported by the "standard" Adobe encoding.
|
| 350 |
+
|
| 351 |
+
adobe controls whether the input sequence is in Adobe Ascii85 format (i.e.
|
| 352 |
+
is framed with <~ and ~>).
|
| 353 |
+
|
| 354 |
+
ignorechars should be a byte string containing characters to ignore from the
|
| 355 |
+
input. This should only contain whitespace characters, and by default
|
| 356 |
+
contains all whitespace characters in ASCII.
|
| 357 |
+
|
| 358 |
+
The result is returned as a bytes object.
|
| 359 |
+
"""
|
| 360 |
+
b = _bytes_from_decode_data(b)
|
| 361 |
+
if adobe:
|
| 362 |
+
if not b.endswith(_A85END):
|
| 363 |
+
raise ValueError(
|
| 364 |
+
"Ascii85 encoded byte sequences must end "
|
| 365 |
+
"with {!r}".format(_A85END)
|
| 366 |
+
)
|
| 367 |
+
if b.startswith(_A85START):
|
| 368 |
+
b = b[2:-2] # Strip off start/end markers
|
| 369 |
+
else:
|
| 370 |
+
b = b[:-2]
|
| 371 |
+
#
|
| 372 |
+
# We have to go through this stepwise, so as to ignore spaces and handle
|
| 373 |
+
# special short sequences
|
| 374 |
+
#
|
| 375 |
+
packI = struct.Struct('!I').pack
|
| 376 |
+
decoded = []
|
| 377 |
+
decoded_append = decoded.append
|
| 378 |
+
curr = []
|
| 379 |
+
curr_append = curr.append
|
| 380 |
+
curr_clear = curr.clear
|
| 381 |
+
for x in b + b'u' * 4:
|
| 382 |
+
if b'!'[0] <= x <= b'u'[0]:
|
| 383 |
+
curr_append(x)
|
| 384 |
+
if len(curr) == 5:
|
| 385 |
+
acc = 0
|
| 386 |
+
for x in curr:
|
| 387 |
+
acc = 85 * acc + (x - 33)
|
| 388 |
+
try:
|
| 389 |
+
decoded_append(packI(acc))
|
| 390 |
+
except struct.error:
|
| 391 |
+
raise ValueError('Ascii85 overflow') from None
|
| 392 |
+
curr_clear()
|
| 393 |
+
elif x == b'z'[0]:
|
| 394 |
+
if curr:
|
| 395 |
+
raise ValueError('z inside Ascii85 5-tuple')
|
| 396 |
+
decoded_append(b'\0\0\0\0')
|
| 397 |
+
elif foldspaces and x == b'y'[0]:
|
| 398 |
+
if curr:
|
| 399 |
+
raise ValueError('y inside Ascii85 5-tuple')
|
| 400 |
+
decoded_append(b'\x20\x20\x20\x20')
|
| 401 |
+
elif x in ignorechars:
|
| 402 |
+
# Skip whitespace
|
| 403 |
+
continue
|
| 404 |
+
else:
|
| 405 |
+
raise ValueError('Non-Ascii85 digit found: %c' % x)
|
| 406 |
+
|
| 407 |
+
result = b''.join(decoded)
|
| 408 |
+
padding = 4 - len(curr)
|
| 409 |
+
if padding:
|
| 410 |
+
# Throw away the extra padding
|
| 411 |
+
result = result[:-padding]
|
| 412 |
+
return result
|
| 413 |
+
|
| 414 |
+
# The following code is originally taken (with permission) from Mercurial
|
| 415 |
+
|
| 416 |
+
_b85alphabet = (b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
| 417 |
+
b"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~")
|
| 418 |
+
_b85chars = None
|
| 419 |
+
_b85chars2 = None
|
| 420 |
+
_b85dec = None
|
| 421 |
+
|
| 422 |
+
def b85encode(b, pad=False):
|
| 423 |
+
"""Encode bytes-like object b in base85 format and return a bytes object.
|
| 424 |
+
|
| 425 |
+
If pad is true, the input is padded with b'\\0' so its length is a multiple of
|
| 426 |
+
4 bytes before encoding.
|
| 427 |
+
"""
|
| 428 |
+
global _b85chars, _b85chars2
|
| 429 |
+
# Delay the initialization of tables to not waste memory
|
| 430 |
+
# if the function is never called
|
| 431 |
+
if _b85chars2 is None:
|
| 432 |
+
_b85chars = [bytes((i,)) for i in _b85alphabet]
|
| 433 |
+
_b85chars2 = [(a + b) for a in _b85chars for b in _b85chars]
|
| 434 |
+
return _85encode(b, _b85chars, _b85chars2, pad)
|
| 435 |
+
|
| 436 |
+
def b85decode(b):
|
| 437 |
+
"""Decode the base85-encoded bytes-like object or ASCII string b
|
| 438 |
+
|
| 439 |
+
The result is returned as a bytes object.
|
| 440 |
+
"""
|
| 441 |
+
global _b85dec
|
| 442 |
+
# Delay the initialization of tables to not waste memory
|
| 443 |
+
# if the function is never called
|
| 444 |
+
if _b85dec is None:
|
| 445 |
+
_b85dec = [None] * 256
|
| 446 |
+
for i, c in enumerate(_b85alphabet):
|
| 447 |
+
_b85dec[c] = i
|
| 448 |
+
|
| 449 |
+
b = _bytes_from_decode_data(b)
|
| 450 |
+
padding = (-len(b)) % 5
|
| 451 |
+
b = b + b'~' * padding
|
| 452 |
+
out = []
|
| 453 |
+
packI = struct.Struct('!I').pack
|
| 454 |
+
for i in range(0, len(b), 5):
|
| 455 |
+
chunk = b[i:i + 5]
|
| 456 |
+
acc = 0
|
| 457 |
+
try:
|
| 458 |
+
for c in chunk:
|
| 459 |
+
acc = acc * 85 + _b85dec[c]
|
| 460 |
+
except TypeError:
|
| 461 |
+
for j, c in enumerate(chunk):
|
| 462 |
+
if _b85dec[c] is None:
|
| 463 |
+
raise ValueError('bad base85 character at position %d'
|
| 464 |
+
% (i + j)) from None
|
| 465 |
+
raise
|
| 466 |
+
try:
|
| 467 |
+
out.append(packI(acc))
|
| 468 |
+
except struct.error:
|
| 469 |
+
raise ValueError('base85 overflow in hunk starting at byte %d'
|
| 470 |
+
% i) from None
|
| 471 |
+
|
| 472 |
+
result = b''.join(out)
|
| 473 |
+
if padding:
|
| 474 |
+
result = result[:-padding]
|
| 475 |
+
return result
|
| 476 |
+
|
| 477 |
+
# Legacy interface. This code could be cleaned up since I don't believe
|
| 478 |
+
# binascii has any line length limitations. It just doesn't seem worth it
|
| 479 |
+
# though. The files should be opened in binary mode.
|
| 480 |
+
|
| 481 |
+
MAXLINESIZE = 76 # Excluding the CRLF
|
| 482 |
+
MAXBINSIZE = (MAXLINESIZE//4)*3
|
| 483 |
+
|
| 484 |
+
def encode(input, output):
|
| 485 |
+
"""Encode a file; input and output are binary files."""
|
| 486 |
+
while True:
|
| 487 |
+
s = input.read(MAXBINSIZE)
|
| 488 |
+
if not s:
|
| 489 |
+
break
|
| 490 |
+
while len(s) < MAXBINSIZE:
|
| 491 |
+
ns = input.read(MAXBINSIZE-len(s))
|
| 492 |
+
if not ns:
|
| 493 |
+
break
|
| 494 |
+
s += ns
|
| 495 |
+
line = binascii.b2a_base64(s)
|
| 496 |
+
output.write(line)
|
| 497 |
+
|
| 498 |
+
|
| 499 |
+
def decode(input, output):
|
| 500 |
+
"""Decode a file; input and output are binary files."""
|
| 501 |
+
while True:
|
| 502 |
+
line = input.readline()
|
| 503 |
+
if not line:
|
| 504 |
+
break
|
| 505 |
+
s = binascii.a2b_base64(line)
|
| 506 |
+
output.write(s)
|
| 507 |
+
|
| 508 |
+
def _input_type_check(s):
|
| 509 |
+
try:
|
| 510 |
+
m = memoryview(s)
|
| 511 |
+
except TypeError as err:
|
| 512 |
+
msg = "expected bytes-like object, not %s" % s.__class__.__name__
|
| 513 |
+
raise TypeError(msg) from err
|
| 514 |
+
if m.format not in ('c', 'b', 'B'):
|
| 515 |
+
msg = ("expected single byte elements, not %r from %s" %
|
| 516 |
+
(m.format, s.__class__.__name__))
|
| 517 |
+
raise TypeError(msg)
|
| 518 |
+
if m.ndim != 1:
|
| 519 |
+
msg = ("expected 1-D data, not %d-D data from %s" %
|
| 520 |
+
(m.ndim, s.__class__.__name__))
|
| 521 |
+
raise TypeError(msg)
|
| 522 |
+
|
| 523 |
+
|
| 524 |
+
def encodebytes(s):
|
| 525 |
+
"""Encode a bytestring into a bytes object containing multiple lines
|
| 526 |
+
of base-64 data."""
|
| 527 |
+
_input_type_check(s)
|
| 528 |
+
pieces = []
|
| 529 |
+
for i in range(0, len(s), MAXBINSIZE):
|
| 530 |
+
chunk = s[i : i + MAXBINSIZE]
|
| 531 |
+
pieces.append(binascii.b2a_base64(chunk))
|
| 532 |
+
return b"".join(pieces)
|
| 533 |
+
|
| 534 |
+
def encodestring(s):
|
| 535 |
+
"""Legacy alias of encodebytes()."""
|
| 536 |
+
import warnings
|
| 537 |
+
warnings.warn("encodestring() is a deprecated alias since 3.1, "
|
| 538 |
+
"use encodebytes()",
|
| 539 |
+
DeprecationWarning, 2)
|
| 540 |
+
return encodebytes(s)
|
| 541 |
+
|
| 542 |
+
|
| 543 |
+
def decodebytes(s):
|
| 544 |
+
"""Decode a bytestring of base-64 data into a bytes object."""
|
| 545 |
+
_input_type_check(s)
|
| 546 |
+
return binascii.a2b_base64(s)
|
| 547 |
+
|
| 548 |
+
def decodestring(s):
|
| 549 |
+
"""Legacy alias of decodebytes()."""
|
| 550 |
+
import warnings
|
| 551 |
+
warnings.warn("decodestring() is a deprecated alias since Python 3.1, "
|
| 552 |
+
"use decodebytes()",
|
| 553 |
+
DeprecationWarning, 2)
|
| 554 |
+
return decodebytes(s)
|
| 555 |
+
|
| 556 |
+
|
| 557 |
+
# Usable as a script...
|
| 558 |
+
def main():
|
| 559 |
+
"""Small main program"""
|
| 560 |
+
import sys, getopt
|
| 561 |
+
try:
|
| 562 |
+
opts, args = getopt.getopt(sys.argv[1:], 'deut')
|
| 563 |
+
except getopt.error as msg:
|
| 564 |
+
sys.stdout = sys.stderr
|
| 565 |
+
print(msg)
|
| 566 |
+
print("""usage: %s [-d|-e|-u|-t] [file|-]
|
| 567 |
+
-d, -u: decode
|
| 568 |
+
-e: encode (default)
|
| 569 |
+
-t: encode and decode string 'Aladdin:open sesame'"""%sys.argv[0])
|
| 570 |
+
sys.exit(2)
|
| 571 |
+
func = encode
|
| 572 |
+
for o, a in opts:
|
| 573 |
+
if o == '-e': func = encode
|
| 574 |
+
if o == '-d': func = decode
|
| 575 |
+
if o == '-u': func = decode
|
| 576 |
+
if o == '-t': test(); return
|
| 577 |
+
if args and args[0] != '-':
|
| 578 |
+
with open(args[0], 'rb') as f:
|
| 579 |
+
func(f, sys.stdout.buffer)
|
| 580 |
+
else:
|
| 581 |
+
func(sys.stdin.buffer, sys.stdout.buffer)
|
| 582 |
+
|
| 583 |
+
|
| 584 |
+
def test():
|
| 585 |
+
s0 = b"Aladdin:open sesame"
|
| 586 |
+
print(repr(s0))
|
| 587 |
+
s1 = encodebytes(s0)
|
| 588 |
+
print(repr(s1))
|
| 589 |
+
s2 = decodebytes(s1)
|
| 590 |
+
print(repr(s2))
|
| 591 |
+
assert s0 == s2
|
| 592 |
+
|
| 593 |
+
|
| 594 |
+
if __name__ == '__main__':
|
| 595 |
+
main()
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/bdb.py
ADDED
|
@@ -0,0 +1,880 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Debugger basics"""
|
| 2 |
+
|
| 3 |
+
import fnmatch
|
| 4 |
+
import sys
|
| 5 |
+
import os
|
| 6 |
+
from inspect import CO_GENERATOR, CO_COROUTINE, CO_ASYNC_GENERATOR
|
| 7 |
+
|
| 8 |
+
__all__ = ["BdbQuit", "Bdb", "Breakpoint"]
|
| 9 |
+
|
| 10 |
+
GENERATOR_AND_COROUTINE_FLAGS = CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
class BdbQuit(Exception):
|
| 14 |
+
"""Exception to give up completely."""
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
class Bdb:
|
| 18 |
+
"""Generic Python debugger base class.
|
| 19 |
+
|
| 20 |
+
This class takes care of details of the trace facility;
|
| 21 |
+
a derived class should implement user interaction.
|
| 22 |
+
The standard debugger class (pdb.Pdb) is an example.
|
| 23 |
+
|
| 24 |
+
The optional skip argument must be an iterable of glob-style
|
| 25 |
+
module name patterns. The debugger will not step into frames
|
| 26 |
+
that originate in a module that matches one of these patterns.
|
| 27 |
+
Whether a frame is considered to originate in a certain module
|
| 28 |
+
is determined by the __name__ in the frame globals.
|
| 29 |
+
"""
|
| 30 |
+
|
| 31 |
+
def __init__(self, skip=None):
|
| 32 |
+
self.skip = set(skip) if skip else None
|
| 33 |
+
self.breaks = {}
|
| 34 |
+
self.fncache = {}
|
| 35 |
+
self.frame_returning = None
|
| 36 |
+
|
| 37 |
+
def canonic(self, filename):
|
| 38 |
+
"""Return canonical form of filename.
|
| 39 |
+
|
| 40 |
+
For real filenames, the canonical form is a case-normalized (on
|
| 41 |
+
case insensitive filesystems) absolute path. 'Filenames' with
|
| 42 |
+
angle brackets, such as "<stdin>", generated in interactive
|
| 43 |
+
mode, are returned unchanged.
|
| 44 |
+
"""
|
| 45 |
+
if filename == "<" + filename[1:-1] + ">":
|
| 46 |
+
return filename
|
| 47 |
+
canonic = self.fncache.get(filename)
|
| 48 |
+
if not canonic:
|
| 49 |
+
canonic = os.path.abspath(filename)
|
| 50 |
+
canonic = os.path.normcase(canonic)
|
| 51 |
+
self.fncache[filename] = canonic
|
| 52 |
+
return canonic
|
| 53 |
+
|
| 54 |
+
def reset(self):
|
| 55 |
+
"""Set values of attributes as ready to start debugging."""
|
| 56 |
+
import linecache
|
| 57 |
+
linecache.checkcache()
|
| 58 |
+
self.botframe = None
|
| 59 |
+
self._set_stopinfo(None, None)
|
| 60 |
+
|
| 61 |
+
def trace_dispatch(self, frame, event, arg):
|
| 62 |
+
"""Dispatch a trace function for debugged frames based on the event.
|
| 63 |
+
|
| 64 |
+
This function is installed as the trace function for debugged
|
| 65 |
+
frames. Its return value is the new trace function, which is
|
| 66 |
+
usually itself. The default implementation decides how to
|
| 67 |
+
dispatch a frame, depending on the type of event (passed in as a
|
| 68 |
+
string) that is about to be executed.
|
| 69 |
+
|
| 70 |
+
The event can be one of the following:
|
| 71 |
+
line: A new line of code is going to be executed.
|
| 72 |
+
call: A function is about to be called or another code block
|
| 73 |
+
is entered.
|
| 74 |
+
return: A function or other code block is about to return.
|
| 75 |
+
exception: An exception has occurred.
|
| 76 |
+
c_call: A C function is about to be called.
|
| 77 |
+
c_return: A C function has returned.
|
| 78 |
+
c_exception: A C function has raised an exception.
|
| 79 |
+
|
| 80 |
+
For the Python events, specialized functions (see the dispatch_*()
|
| 81 |
+
methods) are called. For the C events, no action is taken.
|
| 82 |
+
|
| 83 |
+
The arg parameter depends on the previous event.
|
| 84 |
+
"""
|
| 85 |
+
if self.quitting:
|
| 86 |
+
return # None
|
| 87 |
+
if event == 'line':
|
| 88 |
+
return self.dispatch_line(frame)
|
| 89 |
+
if event == 'call':
|
| 90 |
+
return self.dispatch_call(frame, arg)
|
| 91 |
+
if event == 'return':
|
| 92 |
+
return self.dispatch_return(frame, arg)
|
| 93 |
+
if event == 'exception':
|
| 94 |
+
return self.dispatch_exception(frame, arg)
|
| 95 |
+
if event == 'c_call':
|
| 96 |
+
return self.trace_dispatch
|
| 97 |
+
if event == 'c_exception':
|
| 98 |
+
return self.trace_dispatch
|
| 99 |
+
if event == 'c_return':
|
| 100 |
+
return self.trace_dispatch
|
| 101 |
+
print('bdb.Bdb.dispatch: unknown debugging event:', repr(event))
|
| 102 |
+
return self.trace_dispatch
|
| 103 |
+
|
| 104 |
+
def dispatch_line(self, frame):
|
| 105 |
+
"""Invoke user function and return trace function for line event.
|
| 106 |
+
|
| 107 |
+
If the debugger stops on the current line, invoke
|
| 108 |
+
self.user_line(). Raise BdbQuit if self.quitting is set.
|
| 109 |
+
Return self.trace_dispatch to continue tracing in this scope.
|
| 110 |
+
"""
|
| 111 |
+
if self.stop_here(frame) or self.break_here(frame):
|
| 112 |
+
self.user_line(frame)
|
| 113 |
+
if self.quitting: raise BdbQuit
|
| 114 |
+
return self.trace_dispatch
|
| 115 |
+
|
| 116 |
+
def dispatch_call(self, frame, arg):
|
| 117 |
+
"""Invoke user function and return trace function for call event.
|
| 118 |
+
|
| 119 |
+
If the debugger stops on this function call, invoke
|
| 120 |
+
self.user_call(). Raise BbdQuit if self.quitting is set.
|
| 121 |
+
Return self.trace_dispatch to continue tracing in this scope.
|
| 122 |
+
"""
|
| 123 |
+
# XXX 'arg' is no longer used
|
| 124 |
+
if self.botframe is None:
|
| 125 |
+
# First call of dispatch since reset()
|
| 126 |
+
self.botframe = frame.f_back # (CT) Note that this may also be None!
|
| 127 |
+
return self.trace_dispatch
|
| 128 |
+
if not (self.stop_here(frame) or self.break_anywhere(frame)):
|
| 129 |
+
# No need to trace this function
|
| 130 |
+
return # None
|
| 131 |
+
# Ignore call events in generator except when stepping.
|
| 132 |
+
if self.stopframe and frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS:
|
| 133 |
+
return self.trace_dispatch
|
| 134 |
+
self.user_call(frame, arg)
|
| 135 |
+
if self.quitting: raise BdbQuit
|
| 136 |
+
return self.trace_dispatch
|
| 137 |
+
|
| 138 |
+
def dispatch_return(self, frame, arg):
|
| 139 |
+
"""Invoke user function and return trace function for return event.
|
| 140 |
+
|
| 141 |
+
If the debugger stops on this function return, invoke
|
| 142 |
+
self.user_return(). Raise BdbQuit if self.quitting is set.
|
| 143 |
+
Return self.trace_dispatch to continue tracing in this scope.
|
| 144 |
+
"""
|
| 145 |
+
if self.stop_here(frame) or frame == self.returnframe:
|
| 146 |
+
# Ignore return events in generator except when stepping.
|
| 147 |
+
if self.stopframe and frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS:
|
| 148 |
+
return self.trace_dispatch
|
| 149 |
+
try:
|
| 150 |
+
self.frame_returning = frame
|
| 151 |
+
self.user_return(frame, arg)
|
| 152 |
+
finally:
|
| 153 |
+
self.frame_returning = None
|
| 154 |
+
if self.quitting: raise BdbQuit
|
| 155 |
+
# The user issued a 'next' or 'until' command.
|
| 156 |
+
if self.stopframe is frame and self.stoplineno != -1:
|
| 157 |
+
self._set_stopinfo(None, None)
|
| 158 |
+
return self.trace_dispatch
|
| 159 |
+
|
| 160 |
+
def dispatch_exception(self, frame, arg):
|
| 161 |
+
"""Invoke user function and return trace function for exception event.
|
| 162 |
+
|
| 163 |
+
If the debugger stops on this exception, invoke
|
| 164 |
+
self.user_exception(). Raise BdbQuit if self.quitting is set.
|
| 165 |
+
Return self.trace_dispatch to continue tracing in this scope.
|
| 166 |
+
"""
|
| 167 |
+
if self.stop_here(frame):
|
| 168 |
+
# When stepping with next/until/return in a generator frame, skip
|
| 169 |
+
# the internal StopIteration exception (with no traceback)
|
| 170 |
+
# triggered by a subiterator run with the 'yield from' statement.
|
| 171 |
+
if not (frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS
|
| 172 |
+
and arg[0] is StopIteration and arg[2] is None):
|
| 173 |
+
self.user_exception(frame, arg)
|
| 174 |
+
if self.quitting: raise BdbQuit
|
| 175 |
+
# Stop at the StopIteration or GeneratorExit exception when the user
|
| 176 |
+
# has set stopframe in a generator by issuing a return command, or a
|
| 177 |
+
# next/until command at the last statement in the generator before the
|
| 178 |
+
# exception.
|
| 179 |
+
elif (self.stopframe and frame is not self.stopframe
|
| 180 |
+
and self.stopframe.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS
|
| 181 |
+
and arg[0] in (StopIteration, GeneratorExit)):
|
| 182 |
+
self.user_exception(frame, arg)
|
| 183 |
+
if self.quitting: raise BdbQuit
|
| 184 |
+
|
| 185 |
+
return self.trace_dispatch
|
| 186 |
+
|
| 187 |
+
# Normally derived classes don't override the following
|
| 188 |
+
# methods, but they may if they want to redefine the
|
| 189 |
+
# definition of stopping and breakpoints.
|
| 190 |
+
|
| 191 |
+
def is_skipped_module(self, module_name):
|
| 192 |
+
"Return True if module_name matches any skip pattern."
|
| 193 |
+
if module_name is None: # some modules do not have names
|
| 194 |
+
return False
|
| 195 |
+
for pattern in self.skip:
|
| 196 |
+
if fnmatch.fnmatch(module_name, pattern):
|
| 197 |
+
return True
|
| 198 |
+
return False
|
| 199 |
+
|
| 200 |
+
def stop_here(self, frame):
|
| 201 |
+
"Return True if frame is below the starting frame in the stack."
|
| 202 |
+
# (CT) stopframe may now also be None, see dispatch_call.
|
| 203 |
+
# (CT) the former test for None is therefore removed from here.
|
| 204 |
+
if self.skip and \
|
| 205 |
+
self.is_skipped_module(frame.f_globals.get('__name__')):
|
| 206 |
+
return False
|
| 207 |
+
if frame is self.stopframe:
|
| 208 |
+
if self.stoplineno == -1:
|
| 209 |
+
return False
|
| 210 |
+
return frame.f_lineno >= self.stoplineno
|
| 211 |
+
if not self.stopframe:
|
| 212 |
+
return True
|
| 213 |
+
return False
|
| 214 |
+
|
| 215 |
+
def break_here(self, frame):
|
| 216 |
+
"""Return True if there is an effective breakpoint for this line.
|
| 217 |
+
|
| 218 |
+
Check for line or function breakpoint and if in effect.
|
| 219 |
+
Delete temporary breakpoints if effective() says to.
|
| 220 |
+
"""
|
| 221 |
+
filename = self.canonic(frame.f_code.co_filename)
|
| 222 |
+
if filename not in self.breaks:
|
| 223 |
+
return False
|
| 224 |
+
lineno = frame.f_lineno
|
| 225 |
+
if lineno not in self.breaks[filename]:
|
| 226 |
+
# The line itself has no breakpoint, but maybe the line is the
|
| 227 |
+
# first line of a function with breakpoint set by function name.
|
| 228 |
+
lineno = frame.f_code.co_firstlineno
|
| 229 |
+
if lineno not in self.breaks[filename]:
|
| 230 |
+
return False
|
| 231 |
+
|
| 232 |
+
# flag says ok to delete temp. bp
|
| 233 |
+
(bp, flag) = effective(filename, lineno, frame)
|
| 234 |
+
if bp:
|
| 235 |
+
self.currentbp = bp.number
|
| 236 |
+
if (flag and bp.temporary):
|
| 237 |
+
self.do_clear(str(bp.number))
|
| 238 |
+
return True
|
| 239 |
+
else:
|
| 240 |
+
return False
|
| 241 |
+
|
| 242 |
+
def do_clear(self, arg):
|
| 243 |
+
"""Remove temporary breakpoint.
|
| 244 |
+
|
| 245 |
+
Must implement in derived classes or get NotImplementedError.
|
| 246 |
+
"""
|
| 247 |
+
raise NotImplementedError("subclass of bdb must implement do_clear()")
|
| 248 |
+
|
| 249 |
+
def break_anywhere(self, frame):
|
| 250 |
+
"""Return True if there is any breakpoint for frame's filename.
|
| 251 |
+
"""
|
| 252 |
+
return self.canonic(frame.f_code.co_filename) in self.breaks
|
| 253 |
+
|
| 254 |
+
# Derived classes should override the user_* methods
|
| 255 |
+
# to gain control.
|
| 256 |
+
|
| 257 |
+
def user_call(self, frame, argument_list):
|
| 258 |
+
"""Called if we might stop in a function."""
|
| 259 |
+
pass
|
| 260 |
+
|
| 261 |
+
def user_line(self, frame):
|
| 262 |
+
"""Called when we stop or break at a line."""
|
| 263 |
+
pass
|
| 264 |
+
|
| 265 |
+
def user_return(self, frame, return_value):
|
| 266 |
+
"""Called when a return trap is set here."""
|
| 267 |
+
pass
|
| 268 |
+
|
| 269 |
+
def user_exception(self, frame, exc_info):
|
| 270 |
+
"""Called when we stop on an exception."""
|
| 271 |
+
pass
|
| 272 |
+
|
| 273 |
+
def _set_stopinfo(self, stopframe, returnframe, stoplineno=0):
|
| 274 |
+
"""Set the attributes for stopping.
|
| 275 |
+
|
| 276 |
+
If stoplineno is greater than or equal to 0, then stop at line
|
| 277 |
+
greater than or equal to the stopline. If stoplineno is -1, then
|
| 278 |
+
don't stop at all.
|
| 279 |
+
"""
|
| 280 |
+
self.stopframe = stopframe
|
| 281 |
+
self.returnframe = returnframe
|
| 282 |
+
self.quitting = False
|
| 283 |
+
# stoplineno >= 0 means: stop at line >= the stoplineno
|
| 284 |
+
# stoplineno -1 means: don't stop at all
|
| 285 |
+
self.stoplineno = stoplineno
|
| 286 |
+
|
| 287 |
+
# Derived classes and clients can call the following methods
|
| 288 |
+
# to affect the stepping state.
|
| 289 |
+
|
| 290 |
+
def set_until(self, frame, lineno=None):
|
| 291 |
+
"""Stop when the line with the lineno greater than the current one is
|
| 292 |
+
reached or when returning from current frame."""
|
| 293 |
+
# the name "until" is borrowed from gdb
|
| 294 |
+
if lineno is None:
|
| 295 |
+
lineno = frame.f_lineno + 1
|
| 296 |
+
self._set_stopinfo(frame, frame, lineno)
|
| 297 |
+
|
| 298 |
+
def set_step(self):
|
| 299 |
+
"""Stop after one line of code."""
|
| 300 |
+
# Issue #13183: pdb skips frames after hitting a breakpoint and running
|
| 301 |
+
# step commands.
|
| 302 |
+
# Restore the trace function in the caller (that may not have been set
|
| 303 |
+
# for performance reasons) when returning from the current frame.
|
| 304 |
+
if self.frame_returning:
|
| 305 |
+
caller_frame = self.frame_returning.f_back
|
| 306 |
+
if caller_frame and not caller_frame.f_trace:
|
| 307 |
+
caller_frame.f_trace = self.trace_dispatch
|
| 308 |
+
self._set_stopinfo(None, None)
|
| 309 |
+
|
| 310 |
+
def set_next(self, frame):
|
| 311 |
+
"""Stop on the next line in or below the given frame."""
|
| 312 |
+
self._set_stopinfo(frame, None)
|
| 313 |
+
|
| 314 |
+
def set_return(self, frame):
|
| 315 |
+
"""Stop when returning from the given frame."""
|
| 316 |
+
if frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS:
|
| 317 |
+
self._set_stopinfo(frame, None, -1)
|
| 318 |
+
else:
|
| 319 |
+
self._set_stopinfo(frame.f_back, frame)
|
| 320 |
+
|
| 321 |
+
def set_trace(self, frame=None):
|
| 322 |
+
"""Start debugging from frame.
|
| 323 |
+
|
| 324 |
+
If frame is not specified, debugging starts from caller's frame.
|
| 325 |
+
"""
|
| 326 |
+
if frame is None:
|
| 327 |
+
frame = sys._getframe().f_back
|
| 328 |
+
self.reset()
|
| 329 |
+
while frame:
|
| 330 |
+
frame.f_trace = self.trace_dispatch
|
| 331 |
+
self.botframe = frame
|
| 332 |
+
frame = frame.f_back
|
| 333 |
+
self.set_step()
|
| 334 |
+
sys.settrace(self.trace_dispatch)
|
| 335 |
+
|
| 336 |
+
def set_continue(self):
|
| 337 |
+
"""Stop only at breakpoints or when finished.
|
| 338 |
+
|
| 339 |
+
If there are no breakpoints, set the system trace function to None.
|
| 340 |
+
"""
|
| 341 |
+
# Don't stop except at breakpoints or when finished
|
| 342 |
+
self._set_stopinfo(self.botframe, None, -1)
|
| 343 |
+
if not self.breaks:
|
| 344 |
+
# no breakpoints; run without debugger overhead
|
| 345 |
+
sys.settrace(None)
|
| 346 |
+
frame = sys._getframe().f_back
|
| 347 |
+
while frame and frame is not self.botframe:
|
| 348 |
+
del frame.f_trace
|
| 349 |
+
frame = frame.f_back
|
| 350 |
+
|
| 351 |
+
def set_quit(self):
|
| 352 |
+
"""Set quitting attribute to True.
|
| 353 |
+
|
| 354 |
+
Raises BdbQuit exception in the next call to a dispatch_*() method.
|
| 355 |
+
"""
|
| 356 |
+
self.stopframe = self.botframe
|
| 357 |
+
self.returnframe = None
|
| 358 |
+
self.quitting = True
|
| 359 |
+
sys.settrace(None)
|
| 360 |
+
|
| 361 |
+
# Derived classes and clients can call the following methods
|
| 362 |
+
# to manipulate breakpoints. These methods return an
|
| 363 |
+
# error message if something went wrong, None if all is well.
|
| 364 |
+
# Set_break prints out the breakpoint line and file:lineno.
|
| 365 |
+
# Call self.get_*break*() to see the breakpoints or better
|
| 366 |
+
# for bp in Breakpoint.bpbynumber: if bp: bp.bpprint().
|
| 367 |
+
|
| 368 |
+
def set_break(self, filename, lineno, temporary=False, cond=None,
|
| 369 |
+
funcname=None):
|
| 370 |
+
"""Set a new breakpoint for filename:lineno.
|
| 371 |
+
|
| 372 |
+
If lineno doesn't exist for the filename, return an error message.
|
| 373 |
+
The filename should be in canonical form.
|
| 374 |
+
"""
|
| 375 |
+
filename = self.canonic(filename)
|
| 376 |
+
import linecache # Import as late as possible
|
| 377 |
+
line = linecache.getline(filename, lineno)
|
| 378 |
+
if not line:
|
| 379 |
+
return 'Line %s:%d does not exist' % (filename, lineno)
|
| 380 |
+
list = self.breaks.setdefault(filename, [])
|
| 381 |
+
if lineno not in list:
|
| 382 |
+
list.append(lineno)
|
| 383 |
+
bp = Breakpoint(filename, lineno, temporary, cond, funcname)
|
| 384 |
+
return None
|
| 385 |
+
|
| 386 |
+
def _prune_breaks(self, filename, lineno):
|
| 387 |
+
"""Prune breakpoints for filename:lineno.
|
| 388 |
+
|
| 389 |
+
A list of breakpoints is maintained in the Bdb instance and in
|
| 390 |
+
the Breakpoint class. If a breakpoint in the Bdb instance no
|
| 391 |
+
longer exists in the Breakpoint class, then it's removed from the
|
| 392 |
+
Bdb instance.
|
| 393 |
+
"""
|
| 394 |
+
if (filename, lineno) not in Breakpoint.bplist:
|
| 395 |
+
self.breaks[filename].remove(lineno)
|
| 396 |
+
if not self.breaks[filename]:
|
| 397 |
+
del self.breaks[filename]
|
| 398 |
+
|
| 399 |
+
def clear_break(self, filename, lineno):
|
| 400 |
+
"""Delete breakpoints for filename:lineno.
|
| 401 |
+
|
| 402 |
+
If no breakpoints were set, return an error message.
|
| 403 |
+
"""
|
| 404 |
+
filename = self.canonic(filename)
|
| 405 |
+
if filename not in self.breaks:
|
| 406 |
+
return 'There are no breakpoints in %s' % filename
|
| 407 |
+
if lineno not in self.breaks[filename]:
|
| 408 |
+
return 'There is no breakpoint at %s:%d' % (filename, lineno)
|
| 409 |
+
# If there's only one bp in the list for that file,line
|
| 410 |
+
# pair, then remove the breaks entry
|
| 411 |
+
for bp in Breakpoint.bplist[filename, lineno][:]:
|
| 412 |
+
bp.deleteMe()
|
| 413 |
+
self._prune_breaks(filename, lineno)
|
| 414 |
+
return None
|
| 415 |
+
|
| 416 |
+
def clear_bpbynumber(self, arg):
|
| 417 |
+
"""Delete a breakpoint by its index in Breakpoint.bpbynumber.
|
| 418 |
+
|
| 419 |
+
If arg is invalid, return an error message.
|
| 420 |
+
"""
|
| 421 |
+
try:
|
| 422 |
+
bp = self.get_bpbynumber(arg)
|
| 423 |
+
except ValueError as err:
|
| 424 |
+
return str(err)
|
| 425 |
+
bp.deleteMe()
|
| 426 |
+
self._prune_breaks(bp.file, bp.line)
|
| 427 |
+
return None
|
| 428 |
+
|
| 429 |
+
def clear_all_file_breaks(self, filename):
|
| 430 |
+
"""Delete all breakpoints in filename.
|
| 431 |
+
|
| 432 |
+
If none were set, return an error message.
|
| 433 |
+
"""
|
| 434 |
+
filename = self.canonic(filename)
|
| 435 |
+
if filename not in self.breaks:
|
| 436 |
+
return 'There are no breakpoints in %s' % filename
|
| 437 |
+
for line in self.breaks[filename]:
|
| 438 |
+
blist = Breakpoint.bplist[filename, line]
|
| 439 |
+
for bp in blist:
|
| 440 |
+
bp.deleteMe()
|
| 441 |
+
del self.breaks[filename]
|
| 442 |
+
return None
|
| 443 |
+
|
| 444 |
+
def clear_all_breaks(self):
|
| 445 |
+
"""Delete all existing breakpoints.
|
| 446 |
+
|
| 447 |
+
If none were set, return an error message.
|
| 448 |
+
"""
|
| 449 |
+
if not self.breaks:
|
| 450 |
+
return 'There are no breakpoints'
|
| 451 |
+
for bp in Breakpoint.bpbynumber:
|
| 452 |
+
if bp:
|
| 453 |
+
bp.deleteMe()
|
| 454 |
+
self.breaks = {}
|
| 455 |
+
return None
|
| 456 |
+
|
| 457 |
+
def get_bpbynumber(self, arg):
|
| 458 |
+
"""Return a breakpoint by its index in Breakpoint.bybpnumber.
|
| 459 |
+
|
| 460 |
+
For invalid arg values or if the breakpoint doesn't exist,
|
| 461 |
+
raise a ValueError.
|
| 462 |
+
"""
|
| 463 |
+
if not arg:
|
| 464 |
+
raise ValueError('Breakpoint number expected')
|
| 465 |
+
try:
|
| 466 |
+
number = int(arg)
|
| 467 |
+
except ValueError:
|
| 468 |
+
raise ValueError('Non-numeric breakpoint number %s' % arg) from None
|
| 469 |
+
try:
|
| 470 |
+
bp = Breakpoint.bpbynumber[number]
|
| 471 |
+
except IndexError:
|
| 472 |
+
raise ValueError('Breakpoint number %d out of range' % number) from None
|
| 473 |
+
if bp is None:
|
| 474 |
+
raise ValueError('Breakpoint %d already deleted' % number)
|
| 475 |
+
return bp
|
| 476 |
+
|
| 477 |
+
def get_break(self, filename, lineno):
|
| 478 |
+
"""Return True if there is a breakpoint for filename:lineno."""
|
| 479 |
+
filename = self.canonic(filename)
|
| 480 |
+
return filename in self.breaks and \
|
| 481 |
+
lineno in self.breaks[filename]
|
| 482 |
+
|
| 483 |
+
def get_breaks(self, filename, lineno):
|
| 484 |
+
"""Return all breakpoints for filename:lineno.
|
| 485 |
+
|
| 486 |
+
If no breakpoints are set, return an empty list.
|
| 487 |
+
"""
|
| 488 |
+
filename = self.canonic(filename)
|
| 489 |
+
return filename in self.breaks and \
|
| 490 |
+
lineno in self.breaks[filename] and \
|
| 491 |
+
Breakpoint.bplist[filename, lineno] or []
|
| 492 |
+
|
| 493 |
+
def get_file_breaks(self, filename):
|
| 494 |
+
"""Return all lines with breakpoints for filename.
|
| 495 |
+
|
| 496 |
+
If no breakpoints are set, return an empty list.
|
| 497 |
+
"""
|
| 498 |
+
filename = self.canonic(filename)
|
| 499 |
+
if filename in self.breaks:
|
| 500 |
+
return self.breaks[filename]
|
| 501 |
+
else:
|
| 502 |
+
return []
|
| 503 |
+
|
| 504 |
+
def get_all_breaks(self):
|
| 505 |
+
"""Return all breakpoints that are set."""
|
| 506 |
+
return self.breaks
|
| 507 |
+
|
| 508 |
+
# Derived classes and clients can call the following method
|
| 509 |
+
# to get a data structure representing a stack trace.
|
| 510 |
+
|
| 511 |
+
def get_stack(self, f, t):
|
| 512 |
+
"""Return a list of (frame, lineno) in a stack trace and a size.
|
| 513 |
+
|
| 514 |
+
List starts with original calling frame, if there is one.
|
| 515 |
+
Size may be number of frames above or below f.
|
| 516 |
+
"""
|
| 517 |
+
stack = []
|
| 518 |
+
if t and t.tb_frame is f:
|
| 519 |
+
t = t.tb_next
|
| 520 |
+
while f is not None:
|
| 521 |
+
stack.append((f, f.f_lineno))
|
| 522 |
+
if f is self.botframe:
|
| 523 |
+
break
|
| 524 |
+
f = f.f_back
|
| 525 |
+
stack.reverse()
|
| 526 |
+
i = max(0, len(stack) - 1)
|
| 527 |
+
while t is not None:
|
| 528 |
+
stack.append((t.tb_frame, t.tb_lineno))
|
| 529 |
+
t = t.tb_next
|
| 530 |
+
if f is None:
|
| 531 |
+
i = max(0, len(stack) - 1)
|
| 532 |
+
return stack, i
|
| 533 |
+
|
| 534 |
+
def format_stack_entry(self, frame_lineno, lprefix=': '):
|
| 535 |
+
"""Return a string with information about a stack entry.
|
| 536 |
+
|
| 537 |
+
The stack entry frame_lineno is a (frame, lineno) tuple. The
|
| 538 |
+
return string contains the canonical filename, the function name
|
| 539 |
+
or '<lambda>', the input arguments, the return value, and the
|
| 540 |
+
line of code (if it exists).
|
| 541 |
+
|
| 542 |
+
"""
|
| 543 |
+
import linecache, reprlib
|
| 544 |
+
frame, lineno = frame_lineno
|
| 545 |
+
filename = self.canonic(frame.f_code.co_filename)
|
| 546 |
+
s = '%s(%r)' % (filename, lineno)
|
| 547 |
+
if frame.f_code.co_name:
|
| 548 |
+
s += frame.f_code.co_name
|
| 549 |
+
else:
|
| 550 |
+
s += "<lambda>"
|
| 551 |
+
s += '()'
|
| 552 |
+
if '__return__' in frame.f_locals:
|
| 553 |
+
rv = frame.f_locals['__return__']
|
| 554 |
+
s += '->'
|
| 555 |
+
s += reprlib.repr(rv)
|
| 556 |
+
line = linecache.getline(filename, lineno, frame.f_globals)
|
| 557 |
+
if line:
|
| 558 |
+
s += lprefix + line.strip()
|
| 559 |
+
return s
|
| 560 |
+
|
| 561 |
+
# The following methods can be called by clients to use
|
| 562 |
+
# a debugger to debug a statement or an expression.
|
| 563 |
+
# Both can be given as a string, or a code object.
|
| 564 |
+
|
| 565 |
+
def run(self, cmd, globals=None, locals=None):
|
| 566 |
+
"""Debug a statement executed via the exec() function.
|
| 567 |
+
|
| 568 |
+
globals defaults to __main__.dict; locals defaults to globals.
|
| 569 |
+
"""
|
| 570 |
+
if globals is None:
|
| 571 |
+
import __main__
|
| 572 |
+
globals = __main__.__dict__
|
| 573 |
+
if locals is None:
|
| 574 |
+
locals = globals
|
| 575 |
+
self.reset()
|
| 576 |
+
if isinstance(cmd, str):
|
| 577 |
+
cmd = compile(cmd, "<string>", "exec")
|
| 578 |
+
sys.settrace(self.trace_dispatch)
|
| 579 |
+
try:
|
| 580 |
+
exec(cmd, globals, locals)
|
| 581 |
+
except BdbQuit:
|
| 582 |
+
pass
|
| 583 |
+
finally:
|
| 584 |
+
self.quitting = True
|
| 585 |
+
sys.settrace(None)
|
| 586 |
+
|
| 587 |
+
def runeval(self, expr, globals=None, locals=None):
|
| 588 |
+
"""Debug an expression executed via the eval() function.
|
| 589 |
+
|
| 590 |
+
globals defaults to __main__.dict; locals defaults to globals.
|
| 591 |
+
"""
|
| 592 |
+
if globals is None:
|
| 593 |
+
import __main__
|
| 594 |
+
globals = __main__.__dict__
|
| 595 |
+
if locals is None:
|
| 596 |
+
locals = globals
|
| 597 |
+
self.reset()
|
| 598 |
+
sys.settrace(self.trace_dispatch)
|
| 599 |
+
try:
|
| 600 |
+
return eval(expr, globals, locals)
|
| 601 |
+
except BdbQuit:
|
| 602 |
+
pass
|
| 603 |
+
finally:
|
| 604 |
+
self.quitting = True
|
| 605 |
+
sys.settrace(None)
|
| 606 |
+
|
| 607 |
+
def runctx(self, cmd, globals, locals):
|
| 608 |
+
"""For backwards-compatibility. Defers to run()."""
|
| 609 |
+
# B/W compatibility
|
| 610 |
+
self.run(cmd, globals, locals)
|
| 611 |
+
|
| 612 |
+
# This method is more useful to debug a single function call.
|
| 613 |
+
|
| 614 |
+
def runcall(*args, **kwds):
|
| 615 |
+
"""Debug a single function call.
|
| 616 |
+
|
| 617 |
+
Return the result of the function call.
|
| 618 |
+
"""
|
| 619 |
+
if len(args) >= 2:
|
| 620 |
+
self, func, *args = args
|
| 621 |
+
elif not args:
|
| 622 |
+
raise TypeError("descriptor 'runcall' of 'Bdb' object "
|
| 623 |
+
"needs an argument")
|
| 624 |
+
elif 'func' in kwds:
|
| 625 |
+
func = kwds.pop('func')
|
| 626 |
+
self, *args = args
|
| 627 |
+
import warnings
|
| 628 |
+
warnings.warn("Passing 'func' as keyword argument is deprecated",
|
| 629 |
+
DeprecationWarning, stacklevel=2)
|
| 630 |
+
else:
|
| 631 |
+
raise TypeError('runcall expected at least 1 positional argument, '
|
| 632 |
+
'got %d' % (len(args)-1))
|
| 633 |
+
|
| 634 |
+
self.reset()
|
| 635 |
+
sys.settrace(self.trace_dispatch)
|
| 636 |
+
res = None
|
| 637 |
+
try:
|
| 638 |
+
res = func(*args, **kwds)
|
| 639 |
+
except BdbQuit:
|
| 640 |
+
pass
|
| 641 |
+
finally:
|
| 642 |
+
self.quitting = True
|
| 643 |
+
sys.settrace(None)
|
| 644 |
+
return res
|
| 645 |
+
runcall.__text_signature__ = '($self, func, /, *args, **kwds)'
|
| 646 |
+
|
| 647 |
+
|
| 648 |
+
def set_trace():
|
| 649 |
+
"""Start debugging with a Bdb instance from the caller's frame."""
|
| 650 |
+
Bdb().set_trace()
|
| 651 |
+
|
| 652 |
+
|
| 653 |
+
class Breakpoint:
|
| 654 |
+
"""Breakpoint class.
|
| 655 |
+
|
| 656 |
+
Implements temporary breakpoints, ignore counts, disabling and
|
| 657 |
+
(re)-enabling, and conditionals.
|
| 658 |
+
|
| 659 |
+
Breakpoints are indexed by number through bpbynumber and by
|
| 660 |
+
the (file, line) tuple using bplist. The former points to a
|
| 661 |
+
single instance of class Breakpoint. The latter points to a
|
| 662 |
+
list of such instances since there may be more than one
|
| 663 |
+
breakpoint per line.
|
| 664 |
+
|
| 665 |
+
When creating a breakpoint, its associated filename should be
|
| 666 |
+
in canonical form. If funcname is defined, a breakpoint hit will be
|
| 667 |
+
counted when the first line of that function is executed. A
|
| 668 |
+
conditional breakpoint always counts a hit.
|
| 669 |
+
"""
|
| 670 |
+
|
| 671 |
+
# XXX Keeping state in the class is a mistake -- this means
|
| 672 |
+
# you cannot have more than one active Bdb instance.
|
| 673 |
+
|
| 674 |
+
next = 1 # Next bp to be assigned
|
| 675 |
+
bplist = {} # indexed by (file, lineno) tuple
|
| 676 |
+
bpbynumber = [None] # Each entry is None or an instance of Bpt
|
| 677 |
+
# index 0 is unused, except for marking an
|
| 678 |
+
# effective break .... see effective()
|
| 679 |
+
|
| 680 |
+
def __init__(self, file, line, temporary=False, cond=None, funcname=None):
|
| 681 |
+
self.funcname = funcname
|
| 682 |
+
# Needed if funcname is not None.
|
| 683 |
+
self.func_first_executable_line = None
|
| 684 |
+
self.file = file # This better be in canonical form!
|
| 685 |
+
self.line = line
|
| 686 |
+
self.temporary = temporary
|
| 687 |
+
self.cond = cond
|
| 688 |
+
self.enabled = True
|
| 689 |
+
self.ignore = 0
|
| 690 |
+
self.hits = 0
|
| 691 |
+
self.number = Breakpoint.next
|
| 692 |
+
Breakpoint.next += 1
|
| 693 |
+
# Build the two lists
|
| 694 |
+
self.bpbynumber.append(self)
|
| 695 |
+
if (file, line) in self.bplist:
|
| 696 |
+
self.bplist[file, line].append(self)
|
| 697 |
+
else:
|
| 698 |
+
self.bplist[file, line] = [self]
|
| 699 |
+
|
| 700 |
+
def deleteMe(self):
|
| 701 |
+
"""Delete the breakpoint from the list associated to a file:line.
|
| 702 |
+
|
| 703 |
+
If it is the last breakpoint in that position, it also deletes
|
| 704 |
+
the entry for the file:line.
|
| 705 |
+
"""
|
| 706 |
+
|
| 707 |
+
index = (self.file, self.line)
|
| 708 |
+
self.bpbynumber[self.number] = None # No longer in list
|
| 709 |
+
self.bplist[index].remove(self)
|
| 710 |
+
if not self.bplist[index]:
|
| 711 |
+
# No more bp for this f:l combo
|
| 712 |
+
del self.bplist[index]
|
| 713 |
+
|
| 714 |
+
def enable(self):
|
| 715 |
+
"""Mark the breakpoint as enabled."""
|
| 716 |
+
self.enabled = True
|
| 717 |
+
|
| 718 |
+
def disable(self):
|
| 719 |
+
"""Mark the breakpoint as disabled."""
|
| 720 |
+
self.enabled = False
|
| 721 |
+
|
| 722 |
+
def bpprint(self, out=None):
|
| 723 |
+
"""Print the output of bpformat().
|
| 724 |
+
|
| 725 |
+
The optional out argument directs where the output is sent
|
| 726 |
+
and defaults to standard output.
|
| 727 |
+
"""
|
| 728 |
+
if out is None:
|
| 729 |
+
out = sys.stdout
|
| 730 |
+
print(self.bpformat(), file=out)
|
| 731 |
+
|
| 732 |
+
def bpformat(self):
|
| 733 |
+
"""Return a string with information about the breakpoint.
|
| 734 |
+
|
| 735 |
+
The information includes the breakpoint number, temporary
|
| 736 |
+
status, file:line position, break condition, number of times to
|
| 737 |
+
ignore, and number of times hit.
|
| 738 |
+
|
| 739 |
+
"""
|
| 740 |
+
if self.temporary:
|
| 741 |
+
disp = 'del '
|
| 742 |
+
else:
|
| 743 |
+
disp = 'keep '
|
| 744 |
+
if self.enabled:
|
| 745 |
+
disp = disp + 'yes '
|
| 746 |
+
else:
|
| 747 |
+
disp = disp + 'no '
|
| 748 |
+
ret = '%-4dbreakpoint %s at %s:%d' % (self.number, disp,
|
| 749 |
+
self.file, self.line)
|
| 750 |
+
if self.cond:
|
| 751 |
+
ret += '\n\tstop only if %s' % (self.cond,)
|
| 752 |
+
if self.ignore:
|
| 753 |
+
ret += '\n\tignore next %d hits' % (self.ignore,)
|
| 754 |
+
if self.hits:
|
| 755 |
+
if self.hits > 1:
|
| 756 |
+
ss = 's'
|
| 757 |
+
else:
|
| 758 |
+
ss = ''
|
| 759 |
+
ret += '\n\tbreakpoint already hit %d time%s' % (self.hits, ss)
|
| 760 |
+
return ret
|
| 761 |
+
|
| 762 |
+
def __str__(self):
|
| 763 |
+
"Return a condensed description of the breakpoint."
|
| 764 |
+
return 'breakpoint %s at %s:%s' % (self.number, self.file, self.line)
|
| 765 |
+
|
| 766 |
+
# -----------end of Breakpoint class----------
|
| 767 |
+
|
| 768 |
+
|
| 769 |
+
def checkfuncname(b, frame):
|
| 770 |
+
"""Return True if break should happen here.
|
| 771 |
+
|
| 772 |
+
Whether a break should happen depends on the way that b (the breakpoint)
|
| 773 |
+
was set. If it was set via line number, check if b.line is the same as
|
| 774 |
+
the one in the frame. If it was set via function name, check if this is
|
| 775 |
+
the right function and if it is on the first executable line.
|
| 776 |
+
"""
|
| 777 |
+
if not b.funcname:
|
| 778 |
+
# Breakpoint was set via line number.
|
| 779 |
+
if b.line != frame.f_lineno:
|
| 780 |
+
# Breakpoint was set at a line with a def statement and the function
|
| 781 |
+
# defined is called: don't break.
|
| 782 |
+
return False
|
| 783 |
+
return True
|
| 784 |
+
|
| 785 |
+
# Breakpoint set via function name.
|
| 786 |
+
if frame.f_code.co_name != b.funcname:
|
| 787 |
+
# It's not a function call, but rather execution of def statement.
|
| 788 |
+
return False
|
| 789 |
+
|
| 790 |
+
# We are in the right frame.
|
| 791 |
+
if not b.func_first_executable_line:
|
| 792 |
+
# The function is entered for the 1st time.
|
| 793 |
+
b.func_first_executable_line = frame.f_lineno
|
| 794 |
+
|
| 795 |
+
if b.func_first_executable_line != frame.f_lineno:
|
| 796 |
+
# But we are not at the first line number: don't break.
|
| 797 |
+
return False
|
| 798 |
+
return True
|
| 799 |
+
|
| 800 |
+
|
| 801 |
+
# Determines if there is an effective (active) breakpoint at this
|
| 802 |
+
# line of code. Returns breakpoint number or 0 if none
|
| 803 |
+
def effective(file, line, frame):
|
| 804 |
+
"""Determine which breakpoint for this file:line is to be acted upon.
|
| 805 |
+
|
| 806 |
+
Called only if we know there is a breakpoint at this location. Return
|
| 807 |
+
the breakpoint that was triggered and a boolean that indicates if it is
|
| 808 |
+
ok to delete a temporary breakpoint. Return (None, None) if there is no
|
| 809 |
+
matching breakpoint.
|
| 810 |
+
"""
|
| 811 |
+
possibles = Breakpoint.bplist[file, line]
|
| 812 |
+
for b in possibles:
|
| 813 |
+
if not b.enabled:
|
| 814 |
+
continue
|
| 815 |
+
if not checkfuncname(b, frame):
|
| 816 |
+
continue
|
| 817 |
+
# Count every hit when bp is enabled
|
| 818 |
+
b.hits += 1
|
| 819 |
+
if not b.cond:
|
| 820 |
+
# If unconditional, and ignoring go on to next, else break
|
| 821 |
+
if b.ignore > 0:
|
| 822 |
+
b.ignore -= 1
|
| 823 |
+
continue
|
| 824 |
+
else:
|
| 825 |
+
# breakpoint and marker that it's ok to delete if temporary
|
| 826 |
+
return (b, True)
|
| 827 |
+
else:
|
| 828 |
+
# Conditional bp.
|
| 829 |
+
# Ignore count applies only to those bpt hits where the
|
| 830 |
+
# condition evaluates to true.
|
| 831 |
+
try:
|
| 832 |
+
val = eval(b.cond, frame.f_globals, frame.f_locals)
|
| 833 |
+
if val:
|
| 834 |
+
if b.ignore > 0:
|
| 835 |
+
b.ignore -= 1
|
| 836 |
+
# continue
|
| 837 |
+
else:
|
| 838 |
+
return (b, True)
|
| 839 |
+
# else:
|
| 840 |
+
# continue
|
| 841 |
+
except:
|
| 842 |
+
# if eval fails, most conservative thing is to stop on
|
| 843 |
+
# breakpoint regardless of ignore count. Don't delete
|
| 844 |
+
# temporary, as another hint to user.
|
| 845 |
+
return (b, False)
|
| 846 |
+
return (None, None)
|
| 847 |
+
|
| 848 |
+
|
| 849 |
+
# -------------------- testing --------------------
|
| 850 |
+
|
| 851 |
+
class Tdb(Bdb):
|
| 852 |
+
def user_call(self, frame, args):
|
| 853 |
+
name = frame.f_code.co_name
|
| 854 |
+
if not name: name = '???'
|
| 855 |
+
print('+++ call', name, args)
|
| 856 |
+
def user_line(self, frame):
|
| 857 |
+
import linecache
|
| 858 |
+
name = frame.f_code.co_name
|
| 859 |
+
if not name: name = '???'
|
| 860 |
+
fn = self.canonic(frame.f_code.co_filename)
|
| 861 |
+
line = linecache.getline(fn, frame.f_lineno, frame.f_globals)
|
| 862 |
+
print('+++', fn, frame.f_lineno, name, ':', line.strip())
|
| 863 |
+
def user_return(self, frame, retval):
|
| 864 |
+
print('+++ return', retval)
|
| 865 |
+
def user_exception(self, frame, exc_stuff):
|
| 866 |
+
print('+++ exception', exc_stuff)
|
| 867 |
+
self.set_continue()
|
| 868 |
+
|
| 869 |
+
def foo(n):
|
| 870 |
+
print('foo(', n, ')')
|
| 871 |
+
x = bar(n*10)
|
| 872 |
+
print('bar returned', x)
|
| 873 |
+
|
| 874 |
+
def bar(a):
|
| 875 |
+
print('bar(', a, ')')
|
| 876 |
+
return a/2
|
| 877 |
+
|
| 878 |
+
def test():
|
| 879 |
+
t = Tdb()
|
| 880 |
+
t.run('import bdb; bdb.foo(10)')
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/binhex.py
ADDED
|
@@ -0,0 +1,479 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Macintosh binhex compression/decompression.
|
| 2 |
+
|
| 3 |
+
easy interface:
|
| 4 |
+
binhex(inputfilename, outputfilename)
|
| 5 |
+
hexbin(inputfilename, outputfilename)
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
#
|
| 9 |
+
# Jack Jansen, CWI, August 1995.
|
| 10 |
+
#
|
| 11 |
+
# The module is supposed to be as compatible as possible. Especially the
|
| 12 |
+
# easy interface should work "as expected" on any platform.
|
| 13 |
+
# XXXX Note: currently, textfiles appear in mac-form on all platforms.
|
| 14 |
+
# We seem to lack a simple character-translate in python.
|
| 15 |
+
# (we should probably use ISO-Latin-1 on all but the mac platform).
|
| 16 |
+
# XXXX The simple routines are too simple: they expect to hold the complete
|
| 17 |
+
# files in-core. Should be fixed.
|
| 18 |
+
# XXXX It would be nice to handle AppleDouble format on unix
|
| 19 |
+
# (for servers serving macs).
|
| 20 |
+
# XXXX I don't understand what happens when you get 0x90 times the same byte on
|
| 21 |
+
# input. The resulting code (xx 90 90) would appear to be interpreted as an
|
| 22 |
+
# escaped *value* of 0x90. All coders I've seen appear to ignore this nicety...
|
| 23 |
+
#
|
| 24 |
+
import io
|
| 25 |
+
import os
|
| 26 |
+
import struct
|
| 27 |
+
import binascii
|
| 28 |
+
|
| 29 |
+
__all__ = ["binhex","hexbin","Error"]
|
| 30 |
+
|
| 31 |
+
class Error(Exception):
|
| 32 |
+
pass
|
| 33 |
+
|
| 34 |
+
# States (what have we written)
|
| 35 |
+
_DID_HEADER = 0
|
| 36 |
+
_DID_DATA = 1
|
| 37 |
+
|
| 38 |
+
# Various constants
|
| 39 |
+
REASONABLY_LARGE = 32768 # Minimal amount we pass the rle-coder
|
| 40 |
+
LINELEN = 64
|
| 41 |
+
RUNCHAR = b"\x90"
|
| 42 |
+
|
| 43 |
+
#
|
| 44 |
+
# This code is no longer byte-order dependent
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
class FInfo:
|
| 48 |
+
def __init__(self):
|
| 49 |
+
self.Type = '????'
|
| 50 |
+
self.Creator = '????'
|
| 51 |
+
self.Flags = 0
|
| 52 |
+
|
| 53 |
+
def getfileinfo(name):
|
| 54 |
+
finfo = FInfo()
|
| 55 |
+
with io.open(name, 'rb') as fp:
|
| 56 |
+
# Quick check for textfile
|
| 57 |
+
data = fp.read(512)
|
| 58 |
+
if 0 not in data:
|
| 59 |
+
finfo.Type = 'TEXT'
|
| 60 |
+
fp.seek(0, 2)
|
| 61 |
+
dsize = fp.tell()
|
| 62 |
+
dir, file = os.path.split(name)
|
| 63 |
+
file = file.replace(':', '-', 1)
|
| 64 |
+
return file, finfo, dsize, 0
|
| 65 |
+
|
| 66 |
+
class openrsrc:
|
| 67 |
+
def __init__(self, *args):
|
| 68 |
+
pass
|
| 69 |
+
|
| 70 |
+
def read(self, *args):
|
| 71 |
+
return b''
|
| 72 |
+
|
| 73 |
+
def write(self, *args):
|
| 74 |
+
pass
|
| 75 |
+
|
| 76 |
+
def close(self):
|
| 77 |
+
pass
|
| 78 |
+
|
| 79 |
+
class _Hqxcoderengine:
|
| 80 |
+
"""Write data to the coder in 3-byte chunks"""
|
| 81 |
+
|
| 82 |
+
def __init__(self, ofp):
|
| 83 |
+
self.ofp = ofp
|
| 84 |
+
self.data = b''
|
| 85 |
+
self.hqxdata = b''
|
| 86 |
+
self.linelen = LINELEN - 1
|
| 87 |
+
|
| 88 |
+
def write(self, data):
|
| 89 |
+
self.data = self.data + data
|
| 90 |
+
datalen = len(self.data)
|
| 91 |
+
todo = (datalen // 3) * 3
|
| 92 |
+
data = self.data[:todo]
|
| 93 |
+
self.data = self.data[todo:]
|
| 94 |
+
if not data:
|
| 95 |
+
return
|
| 96 |
+
self.hqxdata = self.hqxdata + binascii.b2a_hqx(data)
|
| 97 |
+
self._flush(0)
|
| 98 |
+
|
| 99 |
+
def _flush(self, force):
|
| 100 |
+
first = 0
|
| 101 |
+
while first <= len(self.hqxdata) - self.linelen:
|
| 102 |
+
last = first + self.linelen
|
| 103 |
+
self.ofp.write(self.hqxdata[first:last] + b'\r')
|
| 104 |
+
self.linelen = LINELEN
|
| 105 |
+
first = last
|
| 106 |
+
self.hqxdata = self.hqxdata[first:]
|
| 107 |
+
if force:
|
| 108 |
+
self.ofp.write(self.hqxdata + b':\r')
|
| 109 |
+
|
| 110 |
+
def close(self):
|
| 111 |
+
if self.data:
|
| 112 |
+
self.hqxdata = self.hqxdata + binascii.b2a_hqx(self.data)
|
| 113 |
+
self._flush(1)
|
| 114 |
+
self.ofp.close()
|
| 115 |
+
del self.ofp
|
| 116 |
+
|
| 117 |
+
class _Rlecoderengine:
|
| 118 |
+
"""Write data to the RLE-coder in suitably large chunks"""
|
| 119 |
+
|
| 120 |
+
def __init__(self, ofp):
|
| 121 |
+
self.ofp = ofp
|
| 122 |
+
self.data = b''
|
| 123 |
+
|
| 124 |
+
def write(self, data):
|
| 125 |
+
self.data = self.data + data
|
| 126 |
+
if len(self.data) < REASONABLY_LARGE:
|
| 127 |
+
return
|
| 128 |
+
rledata = binascii.rlecode_hqx(self.data)
|
| 129 |
+
self.ofp.write(rledata)
|
| 130 |
+
self.data = b''
|
| 131 |
+
|
| 132 |
+
def close(self):
|
| 133 |
+
if self.data:
|
| 134 |
+
rledata = binascii.rlecode_hqx(self.data)
|
| 135 |
+
self.ofp.write(rledata)
|
| 136 |
+
self.ofp.close()
|
| 137 |
+
del self.ofp
|
| 138 |
+
|
| 139 |
+
class BinHex:
|
| 140 |
+
def __init__(self, name_finfo_dlen_rlen, ofp):
|
| 141 |
+
name, finfo, dlen, rlen = name_finfo_dlen_rlen
|
| 142 |
+
close_on_error = False
|
| 143 |
+
if isinstance(ofp, str):
|
| 144 |
+
ofname = ofp
|
| 145 |
+
ofp = io.open(ofname, 'wb')
|
| 146 |
+
close_on_error = True
|
| 147 |
+
try:
|
| 148 |
+
ofp.write(b'(This file must be converted with BinHex 4.0)\r\r:')
|
| 149 |
+
hqxer = _Hqxcoderengine(ofp)
|
| 150 |
+
self.ofp = _Rlecoderengine(hqxer)
|
| 151 |
+
self.crc = 0
|
| 152 |
+
if finfo is None:
|
| 153 |
+
finfo = FInfo()
|
| 154 |
+
self.dlen = dlen
|
| 155 |
+
self.rlen = rlen
|
| 156 |
+
self._writeinfo(name, finfo)
|
| 157 |
+
self.state = _DID_HEADER
|
| 158 |
+
except:
|
| 159 |
+
if close_on_error:
|
| 160 |
+
ofp.close()
|
| 161 |
+
raise
|
| 162 |
+
|
| 163 |
+
def _writeinfo(self, name, finfo):
|
| 164 |
+
nl = len(name)
|
| 165 |
+
if nl > 63:
|
| 166 |
+
raise Error('Filename too long')
|
| 167 |
+
d = bytes([nl]) + name.encode("latin-1") + b'\0'
|
| 168 |
+
tp, cr = finfo.Type, finfo.Creator
|
| 169 |
+
if isinstance(tp, str):
|
| 170 |
+
tp = tp.encode("latin-1")
|
| 171 |
+
if isinstance(cr, str):
|
| 172 |
+
cr = cr.encode("latin-1")
|
| 173 |
+
d2 = tp + cr
|
| 174 |
+
|
| 175 |
+
# Force all structs to be packed with big-endian
|
| 176 |
+
d3 = struct.pack('>h', finfo.Flags)
|
| 177 |
+
d4 = struct.pack('>ii', self.dlen, self.rlen)
|
| 178 |
+
info = d + d2 + d3 + d4
|
| 179 |
+
self._write(info)
|
| 180 |
+
self._writecrc()
|
| 181 |
+
|
| 182 |
+
def _write(self, data):
|
| 183 |
+
self.crc = binascii.crc_hqx(data, self.crc)
|
| 184 |
+
self.ofp.write(data)
|
| 185 |
+
|
| 186 |
+
def _writecrc(self):
|
| 187 |
+
# XXXX Should this be here??
|
| 188 |
+
# self.crc = binascii.crc_hqx('\0\0', self.crc)
|
| 189 |
+
if self.crc < 0:
|
| 190 |
+
fmt = '>h'
|
| 191 |
+
else:
|
| 192 |
+
fmt = '>H'
|
| 193 |
+
self.ofp.write(struct.pack(fmt, self.crc))
|
| 194 |
+
self.crc = 0
|
| 195 |
+
|
| 196 |
+
def write(self, data):
|
| 197 |
+
if self.state != _DID_HEADER:
|
| 198 |
+
raise Error('Writing data at the wrong time')
|
| 199 |
+
self.dlen = self.dlen - len(data)
|
| 200 |
+
self._write(data)
|
| 201 |
+
|
| 202 |
+
def close_data(self):
|
| 203 |
+
if self.dlen != 0:
|
| 204 |
+
raise Error('Incorrect data size, diff=%r' % (self.rlen,))
|
| 205 |
+
self._writecrc()
|
| 206 |
+
self.state = _DID_DATA
|
| 207 |
+
|
| 208 |
+
def write_rsrc(self, data):
|
| 209 |
+
if self.state < _DID_DATA:
|
| 210 |
+
self.close_data()
|
| 211 |
+
if self.state != _DID_DATA:
|
| 212 |
+
raise Error('Writing resource data at the wrong time')
|
| 213 |
+
self.rlen = self.rlen - len(data)
|
| 214 |
+
self._write(data)
|
| 215 |
+
|
| 216 |
+
def close(self):
|
| 217 |
+
if self.state is None:
|
| 218 |
+
return
|
| 219 |
+
try:
|
| 220 |
+
if self.state < _DID_DATA:
|
| 221 |
+
self.close_data()
|
| 222 |
+
if self.state != _DID_DATA:
|
| 223 |
+
raise Error('Close at the wrong time')
|
| 224 |
+
if self.rlen != 0:
|
| 225 |
+
raise Error("Incorrect resource-datasize, diff=%r" % (self.rlen,))
|
| 226 |
+
self._writecrc()
|
| 227 |
+
finally:
|
| 228 |
+
self.state = None
|
| 229 |
+
ofp = self.ofp
|
| 230 |
+
del self.ofp
|
| 231 |
+
ofp.close()
|
| 232 |
+
|
| 233 |
+
def binhex(inp, out):
|
| 234 |
+
"""binhex(infilename, outfilename): create binhex-encoded copy of a file"""
|
| 235 |
+
finfo = getfileinfo(inp)
|
| 236 |
+
ofp = BinHex(finfo, out)
|
| 237 |
+
|
| 238 |
+
with io.open(inp, 'rb') as ifp:
|
| 239 |
+
# XXXX Do textfile translation on non-mac systems
|
| 240 |
+
while True:
|
| 241 |
+
d = ifp.read(128000)
|
| 242 |
+
if not d: break
|
| 243 |
+
ofp.write(d)
|
| 244 |
+
ofp.close_data()
|
| 245 |
+
|
| 246 |
+
ifp = openrsrc(inp, 'rb')
|
| 247 |
+
while True:
|
| 248 |
+
d = ifp.read(128000)
|
| 249 |
+
if not d: break
|
| 250 |
+
ofp.write_rsrc(d)
|
| 251 |
+
ofp.close()
|
| 252 |
+
ifp.close()
|
| 253 |
+
|
| 254 |
+
class _Hqxdecoderengine:
|
| 255 |
+
"""Read data via the decoder in 4-byte chunks"""
|
| 256 |
+
|
| 257 |
+
def __init__(self, ifp):
|
| 258 |
+
self.ifp = ifp
|
| 259 |
+
self.eof = 0
|
| 260 |
+
|
| 261 |
+
def read(self, totalwtd):
|
| 262 |
+
"""Read at least wtd bytes (or until EOF)"""
|
| 263 |
+
decdata = b''
|
| 264 |
+
wtd = totalwtd
|
| 265 |
+
#
|
| 266 |
+
# The loop here is convoluted, since we don't really now how
|
| 267 |
+
# much to decode: there may be newlines in the incoming data.
|
| 268 |
+
while wtd > 0:
|
| 269 |
+
if self.eof: return decdata
|
| 270 |
+
wtd = ((wtd + 2) // 3) * 4
|
| 271 |
+
data = self.ifp.read(wtd)
|
| 272 |
+
#
|
| 273 |
+
# Next problem: there may not be a complete number of
|
| 274 |
+
# bytes in what we pass to a2b. Solve by yet another
|
| 275 |
+
# loop.
|
| 276 |
+
#
|
| 277 |
+
while True:
|
| 278 |
+
try:
|
| 279 |
+
decdatacur, self.eof = binascii.a2b_hqx(data)
|
| 280 |
+
break
|
| 281 |
+
except binascii.Incomplete:
|
| 282 |
+
pass
|
| 283 |
+
newdata = self.ifp.read(1)
|
| 284 |
+
if not newdata:
|
| 285 |
+
raise Error('Premature EOF on binhex file')
|
| 286 |
+
data = data + newdata
|
| 287 |
+
decdata = decdata + decdatacur
|
| 288 |
+
wtd = totalwtd - len(decdata)
|
| 289 |
+
if not decdata and not self.eof:
|
| 290 |
+
raise Error('Premature EOF on binhex file')
|
| 291 |
+
return decdata
|
| 292 |
+
|
| 293 |
+
def close(self):
|
| 294 |
+
self.ifp.close()
|
| 295 |
+
|
| 296 |
+
class _Rledecoderengine:
|
| 297 |
+
"""Read data via the RLE-coder"""
|
| 298 |
+
|
| 299 |
+
def __init__(self, ifp):
|
| 300 |
+
self.ifp = ifp
|
| 301 |
+
self.pre_buffer = b''
|
| 302 |
+
self.post_buffer = b''
|
| 303 |
+
self.eof = 0
|
| 304 |
+
|
| 305 |
+
def read(self, wtd):
|
| 306 |
+
if wtd > len(self.post_buffer):
|
| 307 |
+
self._fill(wtd - len(self.post_buffer))
|
| 308 |
+
rv = self.post_buffer[:wtd]
|
| 309 |
+
self.post_buffer = self.post_buffer[wtd:]
|
| 310 |
+
return rv
|
| 311 |
+
|
| 312 |
+
def _fill(self, wtd):
|
| 313 |
+
self.pre_buffer = self.pre_buffer + self.ifp.read(wtd + 4)
|
| 314 |
+
if self.ifp.eof:
|
| 315 |
+
self.post_buffer = self.post_buffer + \
|
| 316 |
+
binascii.rledecode_hqx(self.pre_buffer)
|
| 317 |
+
self.pre_buffer = b''
|
| 318 |
+
return
|
| 319 |
+
|
| 320 |
+
#
|
| 321 |
+
# Obfuscated code ahead. We have to take care that we don't
|
| 322 |
+
# end up with an orphaned RUNCHAR later on. So, we keep a couple
|
| 323 |
+
# of bytes in the buffer, depending on what the end of
|
| 324 |
+
# the buffer looks like:
|
| 325 |
+
# '\220\0\220' - Keep 3 bytes: repeated \220 (escaped as \220\0)
|
| 326 |
+
# '?\220' - Keep 2 bytes: repeated something-else
|
| 327 |
+
# '\220\0' - Escaped \220: Keep 2 bytes.
|
| 328 |
+
# '?\220?' - Complete repeat sequence: decode all
|
| 329 |
+
# otherwise: keep 1 byte.
|
| 330 |
+
#
|
| 331 |
+
mark = len(self.pre_buffer)
|
| 332 |
+
if self.pre_buffer[-3:] == RUNCHAR + b'\0' + RUNCHAR:
|
| 333 |
+
mark = mark - 3
|
| 334 |
+
elif self.pre_buffer[-1:] == RUNCHAR:
|
| 335 |
+
mark = mark - 2
|
| 336 |
+
elif self.pre_buffer[-2:] == RUNCHAR + b'\0':
|
| 337 |
+
mark = mark - 2
|
| 338 |
+
elif self.pre_buffer[-2:-1] == RUNCHAR:
|
| 339 |
+
pass # Decode all
|
| 340 |
+
else:
|
| 341 |
+
mark = mark - 1
|
| 342 |
+
|
| 343 |
+
self.post_buffer = self.post_buffer + \
|
| 344 |
+
binascii.rledecode_hqx(self.pre_buffer[:mark])
|
| 345 |
+
self.pre_buffer = self.pre_buffer[mark:]
|
| 346 |
+
|
| 347 |
+
def close(self):
|
| 348 |
+
self.ifp.close()
|
| 349 |
+
|
| 350 |
+
class HexBin:
|
| 351 |
+
def __init__(self, ifp):
|
| 352 |
+
if isinstance(ifp, str):
|
| 353 |
+
ifp = io.open(ifp, 'rb')
|
| 354 |
+
#
|
| 355 |
+
# Find initial colon.
|
| 356 |
+
#
|
| 357 |
+
while True:
|
| 358 |
+
ch = ifp.read(1)
|
| 359 |
+
if not ch:
|
| 360 |
+
raise Error("No binhex data found")
|
| 361 |
+
# Cater for \r\n terminated lines (which show up as \n\r, hence
|
| 362 |
+
# all lines start with \r)
|
| 363 |
+
if ch == b'\r':
|
| 364 |
+
continue
|
| 365 |
+
if ch == b':':
|
| 366 |
+
break
|
| 367 |
+
|
| 368 |
+
hqxifp = _Hqxdecoderengine(ifp)
|
| 369 |
+
self.ifp = _Rledecoderengine(hqxifp)
|
| 370 |
+
self.crc = 0
|
| 371 |
+
self._readheader()
|
| 372 |
+
|
| 373 |
+
def _read(self, len):
|
| 374 |
+
data = self.ifp.read(len)
|
| 375 |
+
self.crc = binascii.crc_hqx(data, self.crc)
|
| 376 |
+
return data
|
| 377 |
+
|
| 378 |
+
def _checkcrc(self):
|
| 379 |
+
filecrc = struct.unpack('>h', self.ifp.read(2))[0] & 0xffff
|
| 380 |
+
#self.crc = binascii.crc_hqx('\0\0', self.crc)
|
| 381 |
+
# XXXX Is this needed??
|
| 382 |
+
self.crc = self.crc & 0xffff
|
| 383 |
+
if filecrc != self.crc:
|
| 384 |
+
raise Error('CRC error, computed %x, read %x'
|
| 385 |
+
% (self.crc, filecrc))
|
| 386 |
+
self.crc = 0
|
| 387 |
+
|
| 388 |
+
def _readheader(self):
|
| 389 |
+
len = self._read(1)
|
| 390 |
+
fname = self._read(ord(len))
|
| 391 |
+
rest = self._read(1 + 4 + 4 + 2 + 4 + 4)
|
| 392 |
+
self._checkcrc()
|
| 393 |
+
|
| 394 |
+
type = rest[1:5]
|
| 395 |
+
creator = rest[5:9]
|
| 396 |
+
flags = struct.unpack('>h', rest[9:11])[0]
|
| 397 |
+
self.dlen = struct.unpack('>l', rest[11:15])[0]
|
| 398 |
+
self.rlen = struct.unpack('>l', rest[15:19])[0]
|
| 399 |
+
|
| 400 |
+
self.FName = fname
|
| 401 |
+
self.FInfo = FInfo()
|
| 402 |
+
self.FInfo.Creator = creator
|
| 403 |
+
self.FInfo.Type = type
|
| 404 |
+
self.FInfo.Flags = flags
|
| 405 |
+
|
| 406 |
+
self.state = _DID_HEADER
|
| 407 |
+
|
| 408 |
+
def read(self, *n):
|
| 409 |
+
if self.state != _DID_HEADER:
|
| 410 |
+
raise Error('Read data at wrong time')
|
| 411 |
+
if n:
|
| 412 |
+
n = n[0]
|
| 413 |
+
n = min(n, self.dlen)
|
| 414 |
+
else:
|
| 415 |
+
n = self.dlen
|
| 416 |
+
rv = b''
|
| 417 |
+
while len(rv) < n:
|
| 418 |
+
rv = rv + self._read(n-len(rv))
|
| 419 |
+
self.dlen = self.dlen - n
|
| 420 |
+
return rv
|
| 421 |
+
|
| 422 |
+
def close_data(self):
|
| 423 |
+
if self.state != _DID_HEADER:
|
| 424 |
+
raise Error('close_data at wrong time')
|
| 425 |
+
if self.dlen:
|
| 426 |
+
dummy = self._read(self.dlen)
|
| 427 |
+
self._checkcrc()
|
| 428 |
+
self.state = _DID_DATA
|
| 429 |
+
|
| 430 |
+
def read_rsrc(self, *n):
|
| 431 |
+
if self.state == _DID_HEADER:
|
| 432 |
+
self.close_data()
|
| 433 |
+
if self.state != _DID_DATA:
|
| 434 |
+
raise Error('Read resource data at wrong time')
|
| 435 |
+
if n:
|
| 436 |
+
n = n[0]
|
| 437 |
+
n = min(n, self.rlen)
|
| 438 |
+
else:
|
| 439 |
+
n = self.rlen
|
| 440 |
+
self.rlen = self.rlen - n
|
| 441 |
+
return self._read(n)
|
| 442 |
+
|
| 443 |
+
def close(self):
|
| 444 |
+
if self.state is None:
|
| 445 |
+
return
|
| 446 |
+
try:
|
| 447 |
+
if self.rlen:
|
| 448 |
+
dummy = self.read_rsrc(self.rlen)
|
| 449 |
+
self._checkcrc()
|
| 450 |
+
finally:
|
| 451 |
+
self.state = None
|
| 452 |
+
self.ifp.close()
|
| 453 |
+
|
| 454 |
+
def hexbin(inp, out):
|
| 455 |
+
"""hexbin(infilename, outfilename) - Decode binhexed file"""
|
| 456 |
+
ifp = HexBin(inp)
|
| 457 |
+
finfo = ifp.FInfo
|
| 458 |
+
if not out:
|
| 459 |
+
out = ifp.FName
|
| 460 |
+
|
| 461 |
+
with io.open(out, 'wb') as ofp:
|
| 462 |
+
# XXXX Do translation on non-mac systems
|
| 463 |
+
while True:
|
| 464 |
+
d = ifp.read(128000)
|
| 465 |
+
if not d: break
|
| 466 |
+
ofp.write(d)
|
| 467 |
+
ifp.close_data()
|
| 468 |
+
|
| 469 |
+
d = ifp.read_rsrc(128000)
|
| 470 |
+
if d:
|
| 471 |
+
ofp = openrsrc(out, 'wb')
|
| 472 |
+
ofp.write(d)
|
| 473 |
+
while True:
|
| 474 |
+
d = ifp.read_rsrc(128000)
|
| 475 |
+
if not d: break
|
| 476 |
+
ofp.write(d)
|
| 477 |
+
ofp.close()
|
| 478 |
+
|
| 479 |
+
ifp.close()
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/cProfile.py
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#! /usr/bin/env python3
|
| 2 |
+
|
| 3 |
+
"""Python interface for the 'lsprof' profiler.
|
| 4 |
+
Compatible with the 'profile' module.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
__all__ = ["run", "runctx", "Profile"]
|
| 8 |
+
|
| 9 |
+
import _lsprof
|
| 10 |
+
import io
|
| 11 |
+
import profile as _pyprofile
|
| 12 |
+
|
| 13 |
+
# ____________________________________________________________
|
| 14 |
+
# Simple interface
|
| 15 |
+
|
| 16 |
+
def run(statement, filename=None, sort=-1):
|
| 17 |
+
return _pyprofile._Utils(Profile).run(statement, filename, sort)
|
| 18 |
+
|
| 19 |
+
def runctx(statement, globals, locals, filename=None, sort=-1):
|
| 20 |
+
return _pyprofile._Utils(Profile).runctx(statement, globals, locals,
|
| 21 |
+
filename, sort)
|
| 22 |
+
|
| 23 |
+
run.__doc__ = _pyprofile.run.__doc__
|
| 24 |
+
runctx.__doc__ = _pyprofile.runctx.__doc__
|
| 25 |
+
|
| 26 |
+
# ____________________________________________________________
|
| 27 |
+
|
| 28 |
+
class Profile(_lsprof.Profiler):
|
| 29 |
+
"""Profile(timer=None, timeunit=None, subcalls=True, builtins=True)
|
| 30 |
+
|
| 31 |
+
Builds a profiler object using the specified timer function.
|
| 32 |
+
The default timer is a fast built-in one based on real time.
|
| 33 |
+
For custom timer functions returning integers, timeunit can
|
| 34 |
+
be a float specifying a scale (i.e. how long each integer unit
|
| 35 |
+
is, in seconds).
|
| 36 |
+
"""
|
| 37 |
+
|
| 38 |
+
# Most of the functionality is in the base class.
|
| 39 |
+
# This subclass only adds convenient and backward-compatible methods.
|
| 40 |
+
|
| 41 |
+
def print_stats(self, sort=-1):
|
| 42 |
+
import pstats
|
| 43 |
+
pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats()
|
| 44 |
+
|
| 45 |
+
def dump_stats(self, file):
|
| 46 |
+
import marshal
|
| 47 |
+
with open(file, 'wb') as f:
|
| 48 |
+
self.create_stats()
|
| 49 |
+
marshal.dump(self.stats, f)
|
| 50 |
+
|
| 51 |
+
def create_stats(self):
|
| 52 |
+
self.disable()
|
| 53 |
+
self.snapshot_stats()
|
| 54 |
+
|
| 55 |
+
def snapshot_stats(self):
|
| 56 |
+
entries = self.getstats()
|
| 57 |
+
self.stats = {}
|
| 58 |
+
callersdicts = {}
|
| 59 |
+
# call information
|
| 60 |
+
for entry in entries:
|
| 61 |
+
func = label(entry.code)
|
| 62 |
+
nc = entry.callcount # ncalls column of pstats (before '/')
|
| 63 |
+
cc = nc - entry.reccallcount # ncalls column of pstats (after '/')
|
| 64 |
+
tt = entry.inlinetime # tottime column of pstats
|
| 65 |
+
ct = entry.totaltime # cumtime column of pstats
|
| 66 |
+
callers = {}
|
| 67 |
+
callersdicts[id(entry.code)] = callers
|
| 68 |
+
self.stats[func] = cc, nc, tt, ct, callers
|
| 69 |
+
# subcall information
|
| 70 |
+
for entry in entries:
|
| 71 |
+
if entry.calls:
|
| 72 |
+
func = label(entry.code)
|
| 73 |
+
for subentry in entry.calls:
|
| 74 |
+
try:
|
| 75 |
+
callers = callersdicts[id(subentry.code)]
|
| 76 |
+
except KeyError:
|
| 77 |
+
continue
|
| 78 |
+
nc = subentry.callcount
|
| 79 |
+
cc = nc - subentry.reccallcount
|
| 80 |
+
tt = subentry.inlinetime
|
| 81 |
+
ct = subentry.totaltime
|
| 82 |
+
if func in callers:
|
| 83 |
+
prev = callers[func]
|
| 84 |
+
nc += prev[0]
|
| 85 |
+
cc += prev[1]
|
| 86 |
+
tt += prev[2]
|
| 87 |
+
ct += prev[3]
|
| 88 |
+
callers[func] = nc, cc, tt, ct
|
| 89 |
+
|
| 90 |
+
# The following two methods can be called by clients to use
|
| 91 |
+
# a profiler to profile a statement, given as a string.
|
| 92 |
+
|
| 93 |
+
def run(self, cmd):
|
| 94 |
+
import __main__
|
| 95 |
+
dict = __main__.__dict__
|
| 96 |
+
return self.runctx(cmd, dict, dict)
|
| 97 |
+
|
| 98 |
+
def runctx(self, cmd, globals, locals):
|
| 99 |
+
self.enable()
|
| 100 |
+
try:
|
| 101 |
+
exec(cmd, globals, locals)
|
| 102 |
+
finally:
|
| 103 |
+
self.disable()
|
| 104 |
+
return self
|
| 105 |
+
|
| 106 |
+
# This method is more useful to profile a single function call.
|
| 107 |
+
def runcall(*args, **kw):
|
| 108 |
+
if len(args) >= 2:
|
| 109 |
+
self, func, *args = args
|
| 110 |
+
elif not args:
|
| 111 |
+
raise TypeError("descriptor 'runcall' of 'Profile' object "
|
| 112 |
+
"needs an argument")
|
| 113 |
+
elif 'func' in kw:
|
| 114 |
+
func = kw.pop('func')
|
| 115 |
+
self, *args = args
|
| 116 |
+
import warnings
|
| 117 |
+
warnings.warn("Passing 'func' as keyword argument is deprecated",
|
| 118 |
+
DeprecationWarning, stacklevel=2)
|
| 119 |
+
else:
|
| 120 |
+
raise TypeError('runcall expected at least 1 positional argument, '
|
| 121 |
+
'got %d' % (len(args)-1))
|
| 122 |
+
|
| 123 |
+
self.enable()
|
| 124 |
+
try:
|
| 125 |
+
return func(*args, **kw)
|
| 126 |
+
finally:
|
| 127 |
+
self.disable()
|
| 128 |
+
runcall.__text_signature__ = '($self, func, /, *args, **kw)'
|
| 129 |
+
|
| 130 |
+
def __enter__(self):
|
| 131 |
+
self.enable()
|
| 132 |
+
return self
|
| 133 |
+
|
| 134 |
+
def __exit__(self, *exc_info):
|
| 135 |
+
self.disable()
|
| 136 |
+
|
| 137 |
+
# ____________________________________________________________
|
| 138 |
+
|
| 139 |
+
def label(code):
|
| 140 |
+
if isinstance(code, str):
|
| 141 |
+
return ('~', 0, code) # built-in functions ('~' sorts at the end)
|
| 142 |
+
else:
|
| 143 |
+
return (code.co_filename, code.co_firstlineno, code.co_name)
|
| 144 |
+
|
| 145 |
+
# ____________________________________________________________
|
| 146 |
+
|
| 147 |
+
def main():
|
| 148 |
+
import os
|
| 149 |
+
import sys
|
| 150 |
+
import runpy
|
| 151 |
+
import pstats
|
| 152 |
+
from optparse import OptionParser
|
| 153 |
+
usage = "cProfile.py [-o output_file_path] [-s sort] [-m module | scriptfile] [arg] ..."
|
| 154 |
+
parser = OptionParser(usage=usage)
|
| 155 |
+
parser.allow_interspersed_args = False
|
| 156 |
+
parser.add_option('-o', '--outfile', dest="outfile",
|
| 157 |
+
help="Save stats to <outfile>", default=None)
|
| 158 |
+
parser.add_option('-s', '--sort', dest="sort",
|
| 159 |
+
help="Sort order when printing to stdout, based on pstats.Stats class",
|
| 160 |
+
default=-1,
|
| 161 |
+
choices=sorted(pstats.Stats.sort_arg_dict_default))
|
| 162 |
+
parser.add_option('-m', dest="module", action="store_true",
|
| 163 |
+
help="Profile a library module", default=False)
|
| 164 |
+
|
| 165 |
+
if not sys.argv[1:]:
|
| 166 |
+
parser.print_usage()
|
| 167 |
+
sys.exit(2)
|
| 168 |
+
|
| 169 |
+
(options, args) = parser.parse_args()
|
| 170 |
+
sys.argv[:] = args
|
| 171 |
+
|
| 172 |
+
# The script that we're profiling may chdir, so capture the absolute path
|
| 173 |
+
# to the output file at startup.
|
| 174 |
+
if options.outfile is not None:
|
| 175 |
+
options.outfile = os.path.abspath(options.outfile)
|
| 176 |
+
|
| 177 |
+
if len(args) > 0:
|
| 178 |
+
if options.module:
|
| 179 |
+
code = "run_module(modname, run_name='__main__')"
|
| 180 |
+
globs = {
|
| 181 |
+
'run_module': runpy.run_module,
|
| 182 |
+
'modname': args[0]
|
| 183 |
+
}
|
| 184 |
+
else:
|
| 185 |
+
progname = args[0]
|
| 186 |
+
sys.path.insert(0, os.path.dirname(progname))
|
| 187 |
+
with io.open_code(progname) as fp:
|
| 188 |
+
code = compile(fp.read(), progname, 'exec')
|
| 189 |
+
globs = {
|
| 190 |
+
'__file__': progname,
|
| 191 |
+
'__name__': '__main__',
|
| 192 |
+
'__package__': None,
|
| 193 |
+
'__cached__': None,
|
| 194 |
+
}
|
| 195 |
+
try:
|
| 196 |
+
runctx(code, globs, None, options.outfile, options.sort)
|
| 197 |
+
except BrokenPipeError as exc:
|
| 198 |
+
# Prevent "Exception ignored" during interpreter shutdown.
|
| 199 |
+
sys.stdout = None
|
| 200 |
+
sys.exit(exc.errno)
|
| 201 |
+
else:
|
| 202 |
+
parser.print_usage()
|
| 203 |
+
return parser
|
| 204 |
+
|
| 205 |
+
# When invoked as main program, invoke the profiler on a script
|
| 206 |
+
if __name__ == '__main__':
|
| 207 |
+
main()
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/calendar.py
ADDED
|
@@ -0,0 +1,770 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Calendar printing functions
|
| 2 |
+
|
| 3 |
+
Note when comparing these calendars to the ones printed by cal(1): By
|
| 4 |
+
default, these calendars have Monday as the first day of the week, and
|
| 5 |
+
Sunday as the last (the European convention). Use setfirstweekday() to
|
| 6 |
+
set the first day of the week (0=Monday, 6=Sunday)."""
|
| 7 |
+
|
| 8 |
+
import sys
|
| 9 |
+
import datetime
|
| 10 |
+
import locale as _locale
|
| 11 |
+
from itertools import repeat
|
| 12 |
+
|
| 13 |
+
__all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday",
|
| 14 |
+
"firstweekday", "isleap", "leapdays", "weekday", "monthrange",
|
| 15 |
+
"monthcalendar", "prmonth", "month", "prcal", "calendar",
|
| 16 |
+
"timegm", "month_name", "month_abbr", "day_name", "day_abbr",
|
| 17 |
+
"Calendar", "TextCalendar", "HTMLCalendar", "LocaleTextCalendar",
|
| 18 |
+
"LocaleHTMLCalendar", "weekheader"]
|
| 19 |
+
|
| 20 |
+
# Exception raised for bad input (with string parameter for details)
|
| 21 |
+
error = ValueError
|
| 22 |
+
|
| 23 |
+
# Exceptions raised for bad input
|
| 24 |
+
class IllegalMonthError(ValueError):
|
| 25 |
+
def __init__(self, month):
|
| 26 |
+
self.month = month
|
| 27 |
+
def __str__(self):
|
| 28 |
+
return "bad month number %r; must be 1-12" % self.month
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
class IllegalWeekdayError(ValueError):
|
| 32 |
+
def __init__(self, weekday):
|
| 33 |
+
self.weekday = weekday
|
| 34 |
+
def __str__(self):
|
| 35 |
+
return "bad weekday number %r; must be 0 (Monday) to 6 (Sunday)" % self.weekday
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
# Constants for months referenced later
|
| 39 |
+
January = 1
|
| 40 |
+
February = 2
|
| 41 |
+
|
| 42 |
+
# Number of days per month (except for February in leap years)
|
| 43 |
+
mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
| 44 |
+
|
| 45 |
+
# This module used to have hard-coded lists of day and month names, as
|
| 46 |
+
# English strings. The classes following emulate a read-only version of
|
| 47 |
+
# that, but supply localized names. Note that the values are computed
|
| 48 |
+
# fresh on each call, in case the user changes locale between calls.
|
| 49 |
+
|
| 50 |
+
class _localized_month:
|
| 51 |
+
|
| 52 |
+
_months = [datetime.date(2001, i+1, 1).strftime for i in range(12)]
|
| 53 |
+
_months.insert(0, lambda x: "")
|
| 54 |
+
|
| 55 |
+
def __init__(self, format):
|
| 56 |
+
self.format = format
|
| 57 |
+
|
| 58 |
+
def __getitem__(self, i):
|
| 59 |
+
funcs = self._months[i]
|
| 60 |
+
if isinstance(i, slice):
|
| 61 |
+
return [f(self.format) for f in funcs]
|
| 62 |
+
else:
|
| 63 |
+
return funcs(self.format)
|
| 64 |
+
|
| 65 |
+
def __len__(self):
|
| 66 |
+
return 13
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
class _localized_day:
|
| 70 |
+
|
| 71 |
+
# January 1, 2001, was a Monday.
|
| 72 |
+
_days = [datetime.date(2001, 1, i+1).strftime for i in range(7)]
|
| 73 |
+
|
| 74 |
+
def __init__(self, format):
|
| 75 |
+
self.format = format
|
| 76 |
+
|
| 77 |
+
def __getitem__(self, i):
|
| 78 |
+
funcs = self._days[i]
|
| 79 |
+
if isinstance(i, slice):
|
| 80 |
+
return [f(self.format) for f in funcs]
|
| 81 |
+
else:
|
| 82 |
+
return funcs(self.format)
|
| 83 |
+
|
| 84 |
+
def __len__(self):
|
| 85 |
+
return 7
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
# Full and abbreviated names of weekdays
|
| 89 |
+
day_name = _localized_day('%A')
|
| 90 |
+
day_abbr = _localized_day('%a')
|
| 91 |
+
|
| 92 |
+
# Full and abbreviated names of months (1-based arrays!!!)
|
| 93 |
+
month_name = _localized_month('%B')
|
| 94 |
+
month_abbr = _localized_month('%b')
|
| 95 |
+
|
| 96 |
+
# Constants for weekdays
|
| 97 |
+
(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7)
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def isleap(year):
|
| 101 |
+
"""Return True for leap years, False for non-leap years."""
|
| 102 |
+
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
def leapdays(y1, y2):
|
| 106 |
+
"""Return number of leap years in range [y1, y2).
|
| 107 |
+
Assume y1 <= y2."""
|
| 108 |
+
y1 -= 1
|
| 109 |
+
y2 -= 1
|
| 110 |
+
return (y2//4 - y1//4) - (y2//100 - y1//100) + (y2//400 - y1//400)
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
def weekday(year, month, day):
|
| 114 |
+
"""Return weekday (0-6 ~ Mon-Sun) for year, month (1-12), day (1-31)."""
|
| 115 |
+
if not datetime.MINYEAR <= year <= datetime.MAXYEAR:
|
| 116 |
+
year = 2000 + year % 400
|
| 117 |
+
return datetime.date(year, month, day).weekday()
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
def monthrange(year, month):
|
| 121 |
+
"""Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for
|
| 122 |
+
year, month."""
|
| 123 |
+
if not 1 <= month <= 12:
|
| 124 |
+
raise IllegalMonthError(month)
|
| 125 |
+
day1 = weekday(year, month, 1)
|
| 126 |
+
ndays = mdays[month] + (month == February and isleap(year))
|
| 127 |
+
return day1, ndays
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
def _monthlen(year, month):
|
| 131 |
+
return mdays[month] + (month == February and isleap(year))
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
def _prevmonth(year, month):
|
| 135 |
+
if month == 1:
|
| 136 |
+
return year-1, 12
|
| 137 |
+
else:
|
| 138 |
+
return year, month-1
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def _nextmonth(year, month):
|
| 142 |
+
if month == 12:
|
| 143 |
+
return year+1, 1
|
| 144 |
+
else:
|
| 145 |
+
return year, month+1
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
class Calendar(object):
|
| 149 |
+
"""
|
| 150 |
+
Base calendar class. This class doesn't do any formatting. It simply
|
| 151 |
+
provides data to subclasses.
|
| 152 |
+
"""
|
| 153 |
+
|
| 154 |
+
def __init__(self, firstweekday=0):
|
| 155 |
+
self.firstweekday = firstweekday # 0 = Monday, 6 = Sunday
|
| 156 |
+
|
| 157 |
+
def getfirstweekday(self):
|
| 158 |
+
return self._firstweekday % 7
|
| 159 |
+
|
| 160 |
+
def setfirstweekday(self, firstweekday):
|
| 161 |
+
self._firstweekday = firstweekday
|
| 162 |
+
|
| 163 |
+
firstweekday = property(getfirstweekday, setfirstweekday)
|
| 164 |
+
|
| 165 |
+
def iterweekdays(self):
|
| 166 |
+
"""
|
| 167 |
+
Return an iterator for one week of weekday numbers starting with the
|
| 168 |
+
configured first one.
|
| 169 |
+
"""
|
| 170 |
+
for i in range(self.firstweekday, self.firstweekday + 7):
|
| 171 |
+
yield i%7
|
| 172 |
+
|
| 173 |
+
def itermonthdates(self, year, month):
|
| 174 |
+
"""
|
| 175 |
+
Return an iterator for one month. The iterator will yield datetime.date
|
| 176 |
+
values and will always iterate through complete weeks, so it will yield
|
| 177 |
+
dates outside the specified month.
|
| 178 |
+
"""
|
| 179 |
+
for y, m, d in self.itermonthdays3(year, month):
|
| 180 |
+
yield datetime.date(y, m, d)
|
| 181 |
+
|
| 182 |
+
def itermonthdays(self, year, month):
|
| 183 |
+
"""
|
| 184 |
+
Like itermonthdates(), but will yield day numbers. For days outside
|
| 185 |
+
the specified month the day number is 0.
|
| 186 |
+
"""
|
| 187 |
+
day1, ndays = monthrange(year, month)
|
| 188 |
+
days_before = (day1 - self.firstweekday) % 7
|
| 189 |
+
yield from repeat(0, days_before)
|
| 190 |
+
yield from range(1, ndays + 1)
|
| 191 |
+
days_after = (self.firstweekday - day1 - ndays) % 7
|
| 192 |
+
yield from repeat(0, days_after)
|
| 193 |
+
|
| 194 |
+
def itermonthdays2(self, year, month):
|
| 195 |
+
"""
|
| 196 |
+
Like itermonthdates(), but will yield (day number, weekday number)
|
| 197 |
+
tuples. For days outside the specified month the day number is 0.
|
| 198 |
+
"""
|
| 199 |
+
for i, d in enumerate(self.itermonthdays(year, month), self.firstweekday):
|
| 200 |
+
yield d, i % 7
|
| 201 |
+
|
| 202 |
+
def itermonthdays3(self, year, month):
|
| 203 |
+
"""
|
| 204 |
+
Like itermonthdates(), but will yield (year, month, day) tuples. Can be
|
| 205 |
+
used for dates outside of datetime.date range.
|
| 206 |
+
"""
|
| 207 |
+
day1, ndays = monthrange(year, month)
|
| 208 |
+
days_before = (day1 - self.firstweekday) % 7
|
| 209 |
+
days_after = (self.firstweekday - day1 - ndays) % 7
|
| 210 |
+
y, m = _prevmonth(year, month)
|
| 211 |
+
end = _monthlen(y, m) + 1
|
| 212 |
+
for d in range(end-days_before, end):
|
| 213 |
+
yield y, m, d
|
| 214 |
+
for d in range(1, ndays + 1):
|
| 215 |
+
yield year, month, d
|
| 216 |
+
y, m = _nextmonth(year, month)
|
| 217 |
+
for d in range(1, days_after + 1):
|
| 218 |
+
yield y, m, d
|
| 219 |
+
|
| 220 |
+
def itermonthdays4(self, year, month):
|
| 221 |
+
"""
|
| 222 |
+
Like itermonthdates(), but will yield (year, month, day, day_of_week) tuples.
|
| 223 |
+
Can be used for dates outside of datetime.date range.
|
| 224 |
+
"""
|
| 225 |
+
for i, (y, m, d) in enumerate(self.itermonthdays3(year, month)):
|
| 226 |
+
yield y, m, d, (self.firstweekday + i) % 7
|
| 227 |
+
|
| 228 |
+
def monthdatescalendar(self, year, month):
|
| 229 |
+
"""
|
| 230 |
+
Return a matrix (list of lists) representing a month's calendar.
|
| 231 |
+
Each row represents a week; week entries are datetime.date values.
|
| 232 |
+
"""
|
| 233 |
+
dates = list(self.itermonthdates(year, month))
|
| 234 |
+
return [ dates[i:i+7] for i in range(0, len(dates), 7) ]
|
| 235 |
+
|
| 236 |
+
def monthdays2calendar(self, year, month):
|
| 237 |
+
"""
|
| 238 |
+
Return a matrix representing a month's calendar.
|
| 239 |
+
Each row represents a week; week entries are
|
| 240 |
+
(day number, weekday number) tuples. Day numbers outside this month
|
| 241 |
+
are zero.
|
| 242 |
+
"""
|
| 243 |
+
days = list(self.itermonthdays2(year, month))
|
| 244 |
+
return [ days[i:i+7] for i in range(0, len(days), 7) ]
|
| 245 |
+
|
| 246 |
+
def monthdayscalendar(self, year, month):
|
| 247 |
+
"""
|
| 248 |
+
Return a matrix representing a month's calendar.
|
| 249 |
+
Each row represents a week; days outside this month are zero.
|
| 250 |
+
"""
|
| 251 |
+
days = list(self.itermonthdays(year, month))
|
| 252 |
+
return [ days[i:i+7] for i in range(0, len(days), 7) ]
|
| 253 |
+
|
| 254 |
+
def yeardatescalendar(self, year, width=3):
|
| 255 |
+
"""
|
| 256 |
+
Return the data for the specified year ready for formatting. The return
|
| 257 |
+
value is a list of month rows. Each month row contains up to width months.
|
| 258 |
+
Each month contains between 4 and 6 weeks and each week contains 1-7
|
| 259 |
+
days. Days are datetime.date objects.
|
| 260 |
+
"""
|
| 261 |
+
months = [
|
| 262 |
+
self.monthdatescalendar(year, i)
|
| 263 |
+
for i in range(January, January+12)
|
| 264 |
+
]
|
| 265 |
+
return [months[i:i+width] for i in range(0, len(months), width) ]
|
| 266 |
+
|
| 267 |
+
def yeardays2calendar(self, year, width=3):
|
| 268 |
+
"""
|
| 269 |
+
Return the data for the specified year ready for formatting (similar to
|
| 270 |
+
yeardatescalendar()). Entries in the week lists are
|
| 271 |
+
(day number, weekday number) tuples. Day numbers outside this month are
|
| 272 |
+
zero.
|
| 273 |
+
"""
|
| 274 |
+
months = [
|
| 275 |
+
self.monthdays2calendar(year, i)
|
| 276 |
+
for i in range(January, January+12)
|
| 277 |
+
]
|
| 278 |
+
return [months[i:i+width] for i in range(0, len(months), width) ]
|
| 279 |
+
|
| 280 |
+
def yeardayscalendar(self, year, width=3):
|
| 281 |
+
"""
|
| 282 |
+
Return the data for the specified year ready for formatting (similar to
|
| 283 |
+
yeardatescalendar()). Entries in the week lists are day numbers.
|
| 284 |
+
Day numbers outside this month are zero.
|
| 285 |
+
"""
|
| 286 |
+
months = [
|
| 287 |
+
self.monthdayscalendar(year, i)
|
| 288 |
+
for i in range(January, January+12)
|
| 289 |
+
]
|
| 290 |
+
return [months[i:i+width] for i in range(0, len(months), width) ]
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
class TextCalendar(Calendar):
|
| 294 |
+
"""
|
| 295 |
+
Subclass of Calendar that outputs a calendar as a simple plain text
|
| 296 |
+
similar to the UNIX program cal.
|
| 297 |
+
"""
|
| 298 |
+
|
| 299 |
+
def prweek(self, theweek, width):
|
| 300 |
+
"""
|
| 301 |
+
Print a single week (no newline).
|
| 302 |
+
"""
|
| 303 |
+
print(self.formatweek(theweek, width), end='')
|
| 304 |
+
|
| 305 |
+
def formatday(self, day, weekday, width):
|
| 306 |
+
"""
|
| 307 |
+
Returns a formatted day.
|
| 308 |
+
"""
|
| 309 |
+
if day == 0:
|
| 310 |
+
s = ''
|
| 311 |
+
else:
|
| 312 |
+
s = '%2i' % day # right-align single-digit days
|
| 313 |
+
return s.center(width)
|
| 314 |
+
|
| 315 |
+
def formatweek(self, theweek, width):
|
| 316 |
+
"""
|
| 317 |
+
Returns a single week in a string (no newline).
|
| 318 |
+
"""
|
| 319 |
+
return ' '.join(self.formatday(d, wd, width) for (d, wd) in theweek)
|
| 320 |
+
|
| 321 |
+
def formatweekday(self, day, width):
|
| 322 |
+
"""
|
| 323 |
+
Returns a formatted week day name.
|
| 324 |
+
"""
|
| 325 |
+
if width >= 9:
|
| 326 |
+
names = day_name
|
| 327 |
+
else:
|
| 328 |
+
names = day_abbr
|
| 329 |
+
return names[day][:width].center(width)
|
| 330 |
+
|
| 331 |
+
def formatweekheader(self, width):
|
| 332 |
+
"""
|
| 333 |
+
Return a header for a week.
|
| 334 |
+
"""
|
| 335 |
+
return ' '.join(self.formatweekday(i, width) for i in self.iterweekdays())
|
| 336 |
+
|
| 337 |
+
def formatmonthname(self, theyear, themonth, width, withyear=True):
|
| 338 |
+
"""
|
| 339 |
+
Return a formatted month name.
|
| 340 |
+
"""
|
| 341 |
+
s = month_name[themonth]
|
| 342 |
+
if withyear:
|
| 343 |
+
s = "%s %r" % (s, theyear)
|
| 344 |
+
return s.center(width)
|
| 345 |
+
|
| 346 |
+
def prmonth(self, theyear, themonth, w=0, l=0):
|
| 347 |
+
"""
|
| 348 |
+
Print a month's calendar.
|
| 349 |
+
"""
|
| 350 |
+
print(self.formatmonth(theyear, themonth, w, l), end='')
|
| 351 |
+
|
| 352 |
+
def formatmonth(self, theyear, themonth, w=0, l=0):
|
| 353 |
+
"""
|
| 354 |
+
Return a month's calendar string (multi-line).
|
| 355 |
+
"""
|
| 356 |
+
w = max(2, w)
|
| 357 |
+
l = max(1, l)
|
| 358 |
+
s = self.formatmonthname(theyear, themonth, 7 * (w + 1) - 1)
|
| 359 |
+
s = s.rstrip()
|
| 360 |
+
s += '\n' * l
|
| 361 |
+
s += self.formatweekheader(w).rstrip()
|
| 362 |
+
s += '\n' * l
|
| 363 |
+
for week in self.monthdays2calendar(theyear, themonth):
|
| 364 |
+
s += self.formatweek(week, w).rstrip()
|
| 365 |
+
s += '\n' * l
|
| 366 |
+
return s
|
| 367 |
+
|
| 368 |
+
def formatyear(self, theyear, w=2, l=1, c=6, m=3):
|
| 369 |
+
"""
|
| 370 |
+
Returns a year's calendar as a multi-line string.
|
| 371 |
+
"""
|
| 372 |
+
w = max(2, w)
|
| 373 |
+
l = max(1, l)
|
| 374 |
+
c = max(2, c)
|
| 375 |
+
colwidth = (w + 1) * 7 - 1
|
| 376 |
+
v = []
|
| 377 |
+
a = v.append
|
| 378 |
+
a(repr(theyear).center(colwidth*m+c*(m-1)).rstrip())
|
| 379 |
+
a('\n'*l)
|
| 380 |
+
header = self.formatweekheader(w)
|
| 381 |
+
for (i, row) in enumerate(self.yeardays2calendar(theyear, m)):
|
| 382 |
+
# months in this row
|
| 383 |
+
months = range(m*i+1, min(m*(i+1)+1, 13))
|
| 384 |
+
a('\n'*l)
|
| 385 |
+
names = (self.formatmonthname(theyear, k, colwidth, False)
|
| 386 |
+
for k in months)
|
| 387 |
+
a(formatstring(names, colwidth, c).rstrip())
|
| 388 |
+
a('\n'*l)
|
| 389 |
+
headers = (header for k in months)
|
| 390 |
+
a(formatstring(headers, colwidth, c).rstrip())
|
| 391 |
+
a('\n'*l)
|
| 392 |
+
# max number of weeks for this row
|
| 393 |
+
height = max(len(cal) for cal in row)
|
| 394 |
+
for j in range(height):
|
| 395 |
+
weeks = []
|
| 396 |
+
for cal in row:
|
| 397 |
+
if j >= len(cal):
|
| 398 |
+
weeks.append('')
|
| 399 |
+
else:
|
| 400 |
+
weeks.append(self.formatweek(cal[j], w))
|
| 401 |
+
a(formatstring(weeks, colwidth, c).rstrip())
|
| 402 |
+
a('\n' * l)
|
| 403 |
+
return ''.join(v)
|
| 404 |
+
|
| 405 |
+
def pryear(self, theyear, w=0, l=0, c=6, m=3):
|
| 406 |
+
"""Print a year's calendar."""
|
| 407 |
+
print(self.formatyear(theyear, w, l, c, m), end='')
|
| 408 |
+
|
| 409 |
+
|
| 410 |
+
class HTMLCalendar(Calendar):
|
| 411 |
+
"""
|
| 412 |
+
This calendar returns complete HTML pages.
|
| 413 |
+
"""
|
| 414 |
+
|
| 415 |
+
# CSS classes for the day <td>s
|
| 416 |
+
cssclasses = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
|
| 417 |
+
|
| 418 |
+
# CSS classes for the day <th>s
|
| 419 |
+
cssclasses_weekday_head = cssclasses
|
| 420 |
+
|
| 421 |
+
# CSS class for the days before and after current month
|
| 422 |
+
cssclass_noday = "noday"
|
| 423 |
+
|
| 424 |
+
# CSS class for the month's head
|
| 425 |
+
cssclass_month_head = "month"
|
| 426 |
+
|
| 427 |
+
# CSS class for the month
|
| 428 |
+
cssclass_month = "month"
|
| 429 |
+
|
| 430 |
+
# CSS class for the year's table head
|
| 431 |
+
cssclass_year_head = "year"
|
| 432 |
+
|
| 433 |
+
# CSS class for the whole year table
|
| 434 |
+
cssclass_year = "year"
|
| 435 |
+
|
| 436 |
+
def formatday(self, day, weekday):
|
| 437 |
+
"""
|
| 438 |
+
Return a day as a table cell.
|
| 439 |
+
"""
|
| 440 |
+
if day == 0:
|
| 441 |
+
# day outside month
|
| 442 |
+
return '<td class="%s"> </td>' % self.cssclass_noday
|
| 443 |
+
else:
|
| 444 |
+
return '<td class="%s">%d</td>' % (self.cssclasses[weekday], day)
|
| 445 |
+
|
| 446 |
+
def formatweek(self, theweek):
|
| 447 |
+
"""
|
| 448 |
+
Return a complete week as a table row.
|
| 449 |
+
"""
|
| 450 |
+
s = ''.join(self.formatday(d, wd) for (d, wd) in theweek)
|
| 451 |
+
return '<tr>%s</tr>' % s
|
| 452 |
+
|
| 453 |
+
def formatweekday(self, day):
|
| 454 |
+
"""
|
| 455 |
+
Return a weekday name as a table header.
|
| 456 |
+
"""
|
| 457 |
+
return '<th class="%s">%s</th>' % (
|
| 458 |
+
self.cssclasses_weekday_head[day], day_abbr[day])
|
| 459 |
+
|
| 460 |
+
def formatweekheader(self):
|
| 461 |
+
"""
|
| 462 |
+
Return a header for a week as a table row.
|
| 463 |
+
"""
|
| 464 |
+
s = ''.join(self.formatweekday(i) for i in self.iterweekdays())
|
| 465 |
+
return '<tr>%s</tr>' % s
|
| 466 |
+
|
| 467 |
+
def formatmonthname(self, theyear, themonth, withyear=True):
|
| 468 |
+
"""
|
| 469 |
+
Return a month name as a table row.
|
| 470 |
+
"""
|
| 471 |
+
if withyear:
|
| 472 |
+
s = '%s %s' % (month_name[themonth], theyear)
|
| 473 |
+
else:
|
| 474 |
+
s = '%s' % month_name[themonth]
|
| 475 |
+
return '<tr><th colspan="7" class="%s">%s</th></tr>' % (
|
| 476 |
+
self.cssclass_month_head, s)
|
| 477 |
+
|
| 478 |
+
def formatmonth(self, theyear, themonth, withyear=True):
|
| 479 |
+
"""
|
| 480 |
+
Return a formatted month as a table.
|
| 481 |
+
"""
|
| 482 |
+
v = []
|
| 483 |
+
a = v.append
|
| 484 |
+
a('<table border="0" cellpadding="0" cellspacing="0" class="%s">' % (
|
| 485 |
+
self.cssclass_month))
|
| 486 |
+
a('\n')
|
| 487 |
+
a(self.formatmonthname(theyear, themonth, withyear=withyear))
|
| 488 |
+
a('\n')
|
| 489 |
+
a(self.formatweekheader())
|
| 490 |
+
a('\n')
|
| 491 |
+
for week in self.monthdays2calendar(theyear, themonth):
|
| 492 |
+
a(self.formatweek(week))
|
| 493 |
+
a('\n')
|
| 494 |
+
a('</table>')
|
| 495 |
+
a('\n')
|
| 496 |
+
return ''.join(v)
|
| 497 |
+
|
| 498 |
+
def formatyear(self, theyear, width=3):
|
| 499 |
+
"""
|
| 500 |
+
Return a formatted year as a table of tables.
|
| 501 |
+
"""
|
| 502 |
+
v = []
|
| 503 |
+
a = v.append
|
| 504 |
+
width = max(width, 1)
|
| 505 |
+
a('<table border="0" cellpadding="0" cellspacing="0" class="%s">' %
|
| 506 |
+
self.cssclass_year)
|
| 507 |
+
a('\n')
|
| 508 |
+
a('<tr><th colspan="%d" class="%s">%s</th></tr>' % (
|
| 509 |
+
width, self.cssclass_year_head, theyear))
|
| 510 |
+
for i in range(January, January+12, width):
|
| 511 |
+
# months in this row
|
| 512 |
+
months = range(i, min(i+width, 13))
|
| 513 |
+
a('<tr>')
|
| 514 |
+
for m in months:
|
| 515 |
+
a('<td>')
|
| 516 |
+
a(self.formatmonth(theyear, m, withyear=False))
|
| 517 |
+
a('</td>')
|
| 518 |
+
a('</tr>')
|
| 519 |
+
a('</table>')
|
| 520 |
+
return ''.join(v)
|
| 521 |
+
|
| 522 |
+
def formatyearpage(self, theyear, width=3, css='calendar.css', encoding=None):
|
| 523 |
+
"""
|
| 524 |
+
Return a formatted year as a complete HTML page.
|
| 525 |
+
"""
|
| 526 |
+
if encoding is None:
|
| 527 |
+
encoding = sys.getdefaultencoding()
|
| 528 |
+
v = []
|
| 529 |
+
a = v.append
|
| 530 |
+
a('<?xml version="1.0" encoding="%s"?>\n' % encoding)
|
| 531 |
+
a('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n')
|
| 532 |
+
a('<html>\n')
|
| 533 |
+
a('<head>\n')
|
| 534 |
+
a('<meta http-equiv="Content-Type" content="text/html; charset=%s" />\n' % encoding)
|
| 535 |
+
if css is not None:
|
| 536 |
+
a('<link rel="stylesheet" type="text/css" href="%s" />\n' % css)
|
| 537 |
+
a('<title>Calendar for %d</title>\n' % theyear)
|
| 538 |
+
a('</head>\n')
|
| 539 |
+
a('<body>\n')
|
| 540 |
+
a(self.formatyear(theyear, width))
|
| 541 |
+
a('</body>\n')
|
| 542 |
+
a('</html>\n')
|
| 543 |
+
return ''.join(v).encode(encoding, "xmlcharrefreplace")
|
| 544 |
+
|
| 545 |
+
|
| 546 |
+
class different_locale:
|
| 547 |
+
def __init__(self, locale):
|
| 548 |
+
self.locale = locale
|
| 549 |
+
|
| 550 |
+
def __enter__(self):
|
| 551 |
+
self.oldlocale = _locale.getlocale(_locale.LC_TIME)
|
| 552 |
+
_locale.setlocale(_locale.LC_TIME, self.locale)
|
| 553 |
+
|
| 554 |
+
def __exit__(self, *args):
|
| 555 |
+
_locale.setlocale(_locale.LC_TIME, self.oldlocale)
|
| 556 |
+
|
| 557 |
+
|
| 558 |
+
class LocaleTextCalendar(TextCalendar):
|
| 559 |
+
"""
|
| 560 |
+
This class can be passed a locale name in the constructor and will return
|
| 561 |
+
month and weekday names in the specified locale. If this locale includes
|
| 562 |
+
an encoding all strings containing month and weekday names will be returned
|
| 563 |
+
as unicode.
|
| 564 |
+
"""
|
| 565 |
+
|
| 566 |
+
def __init__(self, firstweekday=0, locale=None):
|
| 567 |
+
TextCalendar.__init__(self, firstweekday)
|
| 568 |
+
if locale is None:
|
| 569 |
+
locale = _locale.getdefaultlocale()
|
| 570 |
+
self.locale = locale
|
| 571 |
+
|
| 572 |
+
def formatweekday(self, day, width):
|
| 573 |
+
with different_locale(self.locale):
|
| 574 |
+
if width >= 9:
|
| 575 |
+
names = day_name
|
| 576 |
+
else:
|
| 577 |
+
names = day_abbr
|
| 578 |
+
name = names[day]
|
| 579 |
+
return name[:width].center(width)
|
| 580 |
+
|
| 581 |
+
def formatmonthname(self, theyear, themonth, width, withyear=True):
|
| 582 |
+
with different_locale(self.locale):
|
| 583 |
+
s = month_name[themonth]
|
| 584 |
+
if withyear:
|
| 585 |
+
s = "%s %r" % (s, theyear)
|
| 586 |
+
return s.center(width)
|
| 587 |
+
|
| 588 |
+
|
| 589 |
+
class LocaleHTMLCalendar(HTMLCalendar):
|
| 590 |
+
"""
|
| 591 |
+
This class can be passed a locale name in the constructor and will return
|
| 592 |
+
month and weekday names in the specified locale. If this locale includes
|
| 593 |
+
an encoding all strings containing month and weekday names will be returned
|
| 594 |
+
as unicode.
|
| 595 |
+
"""
|
| 596 |
+
def __init__(self, firstweekday=0, locale=None):
|
| 597 |
+
HTMLCalendar.__init__(self, firstweekday)
|
| 598 |
+
if locale is None:
|
| 599 |
+
locale = _locale.getdefaultlocale()
|
| 600 |
+
self.locale = locale
|
| 601 |
+
|
| 602 |
+
def formatweekday(self, day):
|
| 603 |
+
with different_locale(self.locale):
|
| 604 |
+
s = day_abbr[day]
|
| 605 |
+
return '<th class="%s">%s</th>' % (self.cssclasses[day], s)
|
| 606 |
+
|
| 607 |
+
def formatmonthname(self, theyear, themonth, withyear=True):
|
| 608 |
+
with different_locale(self.locale):
|
| 609 |
+
s = month_name[themonth]
|
| 610 |
+
if withyear:
|
| 611 |
+
s = '%s %s' % (s, theyear)
|
| 612 |
+
return '<tr><th colspan="7" class="month">%s</th></tr>' % s
|
| 613 |
+
|
| 614 |
+
|
| 615 |
+
# Support for old module level interface
|
| 616 |
+
c = TextCalendar()
|
| 617 |
+
|
| 618 |
+
firstweekday = c.getfirstweekday
|
| 619 |
+
|
| 620 |
+
def setfirstweekday(firstweekday):
|
| 621 |
+
if not MONDAY <= firstweekday <= SUNDAY:
|
| 622 |
+
raise IllegalWeekdayError(firstweekday)
|
| 623 |
+
c.firstweekday = firstweekday
|
| 624 |
+
|
| 625 |
+
monthcalendar = c.monthdayscalendar
|
| 626 |
+
prweek = c.prweek
|
| 627 |
+
week = c.formatweek
|
| 628 |
+
weekheader = c.formatweekheader
|
| 629 |
+
prmonth = c.prmonth
|
| 630 |
+
month = c.formatmonth
|
| 631 |
+
calendar = c.formatyear
|
| 632 |
+
prcal = c.pryear
|
| 633 |
+
|
| 634 |
+
|
| 635 |
+
# Spacing of month columns for multi-column year calendar
|
| 636 |
+
_colwidth = 7*3 - 1 # Amount printed by prweek()
|
| 637 |
+
_spacing = 6 # Number of spaces between columns
|
| 638 |
+
|
| 639 |
+
|
| 640 |
+
def format(cols, colwidth=_colwidth, spacing=_spacing):
|
| 641 |
+
"""Prints multi-column formatting for year calendars"""
|
| 642 |
+
print(formatstring(cols, colwidth, spacing))
|
| 643 |
+
|
| 644 |
+
|
| 645 |
+
def formatstring(cols, colwidth=_colwidth, spacing=_spacing):
|
| 646 |
+
"""Returns a string formatted from n strings, centered within n columns."""
|
| 647 |
+
spacing *= ' '
|
| 648 |
+
return spacing.join(c.center(colwidth) for c in cols)
|
| 649 |
+
|
| 650 |
+
|
| 651 |
+
EPOCH = 1970
|
| 652 |
+
_EPOCH_ORD = datetime.date(EPOCH, 1, 1).toordinal()
|
| 653 |
+
|
| 654 |
+
|
| 655 |
+
def timegm(tuple):
|
| 656 |
+
"""Unrelated but handy function to calculate Unix timestamp from GMT."""
|
| 657 |
+
year, month, day, hour, minute, second = tuple[:6]
|
| 658 |
+
days = datetime.date(year, month, 1).toordinal() - _EPOCH_ORD + day - 1
|
| 659 |
+
hours = days*24 + hour
|
| 660 |
+
minutes = hours*60 + minute
|
| 661 |
+
seconds = minutes*60 + second
|
| 662 |
+
return seconds
|
| 663 |
+
|
| 664 |
+
|
| 665 |
+
def main(args):
|
| 666 |
+
import argparse
|
| 667 |
+
parser = argparse.ArgumentParser()
|
| 668 |
+
textgroup = parser.add_argument_group('text only arguments')
|
| 669 |
+
htmlgroup = parser.add_argument_group('html only arguments')
|
| 670 |
+
textgroup.add_argument(
|
| 671 |
+
"-w", "--width",
|
| 672 |
+
type=int, default=2,
|
| 673 |
+
help="width of date column (default 2)"
|
| 674 |
+
)
|
| 675 |
+
textgroup.add_argument(
|
| 676 |
+
"-l", "--lines",
|
| 677 |
+
type=int, default=1,
|
| 678 |
+
help="number of lines for each week (default 1)"
|
| 679 |
+
)
|
| 680 |
+
textgroup.add_argument(
|
| 681 |
+
"-s", "--spacing",
|
| 682 |
+
type=int, default=6,
|
| 683 |
+
help="spacing between months (default 6)"
|
| 684 |
+
)
|
| 685 |
+
textgroup.add_argument(
|
| 686 |
+
"-m", "--months",
|
| 687 |
+
type=int, default=3,
|
| 688 |
+
help="months per row (default 3)"
|
| 689 |
+
)
|
| 690 |
+
htmlgroup.add_argument(
|
| 691 |
+
"-c", "--css",
|
| 692 |
+
default="calendar.css",
|
| 693 |
+
help="CSS to use for page"
|
| 694 |
+
)
|
| 695 |
+
parser.add_argument(
|
| 696 |
+
"-L", "--locale",
|
| 697 |
+
default=None,
|
| 698 |
+
help="locale to be used from month and weekday names"
|
| 699 |
+
)
|
| 700 |
+
parser.add_argument(
|
| 701 |
+
"-e", "--encoding",
|
| 702 |
+
default=None,
|
| 703 |
+
help="encoding to use for output"
|
| 704 |
+
)
|
| 705 |
+
parser.add_argument(
|
| 706 |
+
"-t", "--type",
|
| 707 |
+
default="text",
|
| 708 |
+
choices=("text", "html"),
|
| 709 |
+
help="output type (text or html)"
|
| 710 |
+
)
|
| 711 |
+
parser.add_argument(
|
| 712 |
+
"year",
|
| 713 |
+
nargs='?', type=int,
|
| 714 |
+
help="year number (1-9999)"
|
| 715 |
+
)
|
| 716 |
+
parser.add_argument(
|
| 717 |
+
"month",
|
| 718 |
+
nargs='?', type=int,
|
| 719 |
+
help="month number (1-12, text only)"
|
| 720 |
+
)
|
| 721 |
+
|
| 722 |
+
options = parser.parse_args(args[1:])
|
| 723 |
+
|
| 724 |
+
if options.locale and not options.encoding:
|
| 725 |
+
parser.error("if --locale is specified --encoding is required")
|
| 726 |
+
sys.exit(1)
|
| 727 |
+
|
| 728 |
+
locale = options.locale, options.encoding
|
| 729 |
+
|
| 730 |
+
if options.type == "html":
|
| 731 |
+
if options.locale:
|
| 732 |
+
cal = LocaleHTMLCalendar(locale=locale)
|
| 733 |
+
else:
|
| 734 |
+
cal = HTMLCalendar()
|
| 735 |
+
encoding = options.encoding
|
| 736 |
+
if encoding is None:
|
| 737 |
+
encoding = sys.getdefaultencoding()
|
| 738 |
+
optdict = dict(encoding=encoding, css=options.css)
|
| 739 |
+
write = sys.stdout.buffer.write
|
| 740 |
+
if options.year is None:
|
| 741 |
+
write(cal.formatyearpage(datetime.date.today().year, **optdict))
|
| 742 |
+
elif options.month is None:
|
| 743 |
+
write(cal.formatyearpage(options.year, **optdict))
|
| 744 |
+
else:
|
| 745 |
+
parser.error("incorrect number of arguments")
|
| 746 |
+
sys.exit(1)
|
| 747 |
+
else:
|
| 748 |
+
if options.locale:
|
| 749 |
+
cal = LocaleTextCalendar(locale=locale)
|
| 750 |
+
else:
|
| 751 |
+
cal = TextCalendar()
|
| 752 |
+
optdict = dict(w=options.width, l=options.lines)
|
| 753 |
+
if options.month is None:
|
| 754 |
+
optdict["c"] = options.spacing
|
| 755 |
+
optdict["m"] = options.months
|
| 756 |
+
if options.year is None:
|
| 757 |
+
result = cal.formatyear(datetime.date.today().year, **optdict)
|
| 758 |
+
elif options.month is None:
|
| 759 |
+
result = cal.formatyear(options.year, **optdict)
|
| 760 |
+
else:
|
| 761 |
+
result = cal.formatmonth(options.year, options.month, **optdict)
|
| 762 |
+
write = sys.stdout.write
|
| 763 |
+
if options.encoding:
|
| 764 |
+
result = result.encode(options.encoding)
|
| 765 |
+
write = sys.stdout.buffer.write
|
| 766 |
+
write(result)
|
| 767 |
+
|
| 768 |
+
|
| 769 |
+
if __name__ == "__main__":
|
| 770 |
+
main(sys.argv)
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/cgi.py
ADDED
|
@@ -0,0 +1,1001 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#! /usr/local/bin/python
|
| 2 |
+
|
| 3 |
+
# NOTE: the above "/usr/local/bin/python" is NOT a mistake. It is
|
| 4 |
+
# intentionally NOT "/usr/bin/env python". On many systems
|
| 5 |
+
# (e.g. Solaris), /usr/local/bin is not in $PATH as passed to CGI
|
| 6 |
+
# scripts, and /usr/local/bin is the default directory where Python is
|
| 7 |
+
# installed, so /usr/bin/env would be unable to find python. Granted,
|
| 8 |
+
# binary installations by Linux vendors often install Python in
|
| 9 |
+
# /usr/bin. So let those vendors patch cgi.py to match their choice
|
| 10 |
+
# of installation.
|
| 11 |
+
|
| 12 |
+
"""Support module for CGI (Common Gateway Interface) scripts.
|
| 13 |
+
|
| 14 |
+
This module defines a number of utilities for use by CGI scripts
|
| 15 |
+
written in Python.
|
| 16 |
+
"""
|
| 17 |
+
|
| 18 |
+
# History
|
| 19 |
+
# -------
|
| 20 |
+
#
|
| 21 |
+
# Michael McLay started this module. Steve Majewski changed the
|
| 22 |
+
# interface to SvFormContentDict and FormContentDict. The multipart
|
| 23 |
+
# parsing was inspired by code submitted by Andreas Paepcke. Guido van
|
| 24 |
+
# Rossum rewrote, reformatted and documented the module and is currently
|
| 25 |
+
# responsible for its maintenance.
|
| 26 |
+
#
|
| 27 |
+
|
| 28 |
+
__version__ = "2.6"
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
# Imports
|
| 32 |
+
# =======
|
| 33 |
+
|
| 34 |
+
from io import StringIO, BytesIO, TextIOWrapper
|
| 35 |
+
from collections.abc import Mapping
|
| 36 |
+
import sys
|
| 37 |
+
import os
|
| 38 |
+
import urllib.parse
|
| 39 |
+
from email.parser import FeedParser
|
| 40 |
+
from email.message import Message
|
| 41 |
+
import html
|
| 42 |
+
import locale
|
| 43 |
+
import tempfile
|
| 44 |
+
|
| 45 |
+
__all__ = ["MiniFieldStorage", "FieldStorage", "parse", "parse_multipart",
|
| 46 |
+
"parse_header", "test", "print_exception", "print_environ",
|
| 47 |
+
"print_form", "print_directory", "print_arguments",
|
| 48 |
+
"print_environ_usage"]
|
| 49 |
+
|
| 50 |
+
# Logging support
|
| 51 |
+
# ===============
|
| 52 |
+
|
| 53 |
+
logfile = "" # Filename to log to, if not empty
|
| 54 |
+
logfp = None # File object to log to, if not None
|
| 55 |
+
|
| 56 |
+
def initlog(*allargs):
|
| 57 |
+
"""Write a log message, if there is a log file.
|
| 58 |
+
|
| 59 |
+
Even though this function is called initlog(), you should always
|
| 60 |
+
use log(); log is a variable that is set either to initlog
|
| 61 |
+
(initially), to dolog (once the log file has been opened), or to
|
| 62 |
+
nolog (when logging is disabled).
|
| 63 |
+
|
| 64 |
+
The first argument is a format string; the remaining arguments (if
|
| 65 |
+
any) are arguments to the % operator, so e.g.
|
| 66 |
+
log("%s: %s", "a", "b")
|
| 67 |
+
will write "a: b" to the log file, followed by a newline.
|
| 68 |
+
|
| 69 |
+
If the global logfp is not None, it should be a file object to
|
| 70 |
+
which log data is written.
|
| 71 |
+
|
| 72 |
+
If the global logfp is None, the global logfile may be a string
|
| 73 |
+
giving a filename to open, in append mode. This file should be
|
| 74 |
+
world writable!!! If the file can't be opened, logging is
|
| 75 |
+
silently disabled (since there is no safe place where we could
|
| 76 |
+
send an error message).
|
| 77 |
+
|
| 78 |
+
"""
|
| 79 |
+
global log, logfile, logfp
|
| 80 |
+
if logfile and not logfp:
|
| 81 |
+
try:
|
| 82 |
+
logfp = open(logfile, "a")
|
| 83 |
+
except OSError:
|
| 84 |
+
pass
|
| 85 |
+
if not logfp:
|
| 86 |
+
log = nolog
|
| 87 |
+
else:
|
| 88 |
+
log = dolog
|
| 89 |
+
log(*allargs)
|
| 90 |
+
|
| 91 |
+
def dolog(fmt, *args):
|
| 92 |
+
"""Write a log message to the log file. See initlog() for docs."""
|
| 93 |
+
logfp.write(fmt%args + "\n")
|
| 94 |
+
|
| 95 |
+
def nolog(*allargs):
|
| 96 |
+
"""Dummy function, assigned to log when logging is disabled."""
|
| 97 |
+
pass
|
| 98 |
+
|
| 99 |
+
def closelog():
|
| 100 |
+
"""Close the log file."""
|
| 101 |
+
global log, logfile, logfp
|
| 102 |
+
logfile = ''
|
| 103 |
+
if logfp:
|
| 104 |
+
logfp.close()
|
| 105 |
+
logfp = None
|
| 106 |
+
log = initlog
|
| 107 |
+
|
| 108 |
+
log = initlog # The current logging function
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
# Parsing functions
|
| 112 |
+
# =================
|
| 113 |
+
|
| 114 |
+
# Maximum input we will accept when REQUEST_METHOD is POST
|
| 115 |
+
# 0 ==> unlimited input
|
| 116 |
+
maxlen = 0
|
| 117 |
+
|
| 118 |
+
def parse(fp=None, environ=os.environ, keep_blank_values=0,
|
| 119 |
+
strict_parsing=0, separator='&'):
|
| 120 |
+
"""Parse a query in the environment or from a file (default stdin)
|
| 121 |
+
|
| 122 |
+
Arguments, all optional:
|
| 123 |
+
|
| 124 |
+
fp : file pointer; default: sys.stdin.buffer
|
| 125 |
+
|
| 126 |
+
environ : environment dictionary; default: os.environ
|
| 127 |
+
|
| 128 |
+
keep_blank_values: flag indicating whether blank values in
|
| 129 |
+
percent-encoded forms should be treated as blank strings.
|
| 130 |
+
A true value indicates that blanks should be retained as
|
| 131 |
+
blank strings. The default false value indicates that
|
| 132 |
+
blank values are to be ignored and treated as if they were
|
| 133 |
+
not included.
|
| 134 |
+
|
| 135 |
+
strict_parsing: flag indicating what to do with parsing errors.
|
| 136 |
+
If false (the default), errors are silently ignored.
|
| 137 |
+
If true, errors raise a ValueError exception.
|
| 138 |
+
|
| 139 |
+
separator: str. The symbol to use for separating the query arguments.
|
| 140 |
+
Defaults to &.
|
| 141 |
+
"""
|
| 142 |
+
if fp is None:
|
| 143 |
+
fp = sys.stdin
|
| 144 |
+
|
| 145 |
+
# field keys and values (except for files) are returned as strings
|
| 146 |
+
# an encoding is required to decode the bytes read from self.fp
|
| 147 |
+
if hasattr(fp,'encoding'):
|
| 148 |
+
encoding = fp.encoding
|
| 149 |
+
else:
|
| 150 |
+
encoding = 'latin-1'
|
| 151 |
+
|
| 152 |
+
# fp.read() must return bytes
|
| 153 |
+
if isinstance(fp, TextIOWrapper):
|
| 154 |
+
fp = fp.buffer
|
| 155 |
+
|
| 156 |
+
if not 'REQUEST_METHOD' in environ:
|
| 157 |
+
environ['REQUEST_METHOD'] = 'GET' # For testing stand-alone
|
| 158 |
+
if environ['REQUEST_METHOD'] == 'POST':
|
| 159 |
+
ctype, pdict = parse_header(environ['CONTENT_TYPE'])
|
| 160 |
+
if ctype == 'multipart/form-data':
|
| 161 |
+
return parse_multipart(fp, pdict, separator=separator)
|
| 162 |
+
elif ctype == 'application/x-www-form-urlencoded':
|
| 163 |
+
clength = int(environ['CONTENT_LENGTH'])
|
| 164 |
+
if maxlen and clength > maxlen:
|
| 165 |
+
raise ValueError('Maximum content length exceeded')
|
| 166 |
+
qs = fp.read(clength).decode(encoding)
|
| 167 |
+
else:
|
| 168 |
+
qs = '' # Unknown content-type
|
| 169 |
+
if 'QUERY_STRING' in environ:
|
| 170 |
+
if qs: qs = qs + '&'
|
| 171 |
+
qs = qs + environ['QUERY_STRING']
|
| 172 |
+
elif sys.argv[1:]:
|
| 173 |
+
if qs: qs = qs + '&'
|
| 174 |
+
qs = qs + sys.argv[1]
|
| 175 |
+
environ['QUERY_STRING'] = qs # XXX Shouldn't, really
|
| 176 |
+
elif 'QUERY_STRING' in environ:
|
| 177 |
+
qs = environ['QUERY_STRING']
|
| 178 |
+
else:
|
| 179 |
+
if sys.argv[1:]:
|
| 180 |
+
qs = sys.argv[1]
|
| 181 |
+
else:
|
| 182 |
+
qs = ""
|
| 183 |
+
environ['QUERY_STRING'] = qs # XXX Shouldn't, really
|
| 184 |
+
return urllib.parse.parse_qs(qs, keep_blank_values, strict_parsing,
|
| 185 |
+
encoding=encoding, separator=separator)
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
def parse_multipart(fp, pdict, encoding="utf-8", errors="replace", separator='&'):
|
| 189 |
+
"""Parse multipart input.
|
| 190 |
+
|
| 191 |
+
Arguments:
|
| 192 |
+
fp : input file
|
| 193 |
+
pdict: dictionary containing other parameters of content-type header
|
| 194 |
+
encoding, errors: request encoding and error handler, passed to
|
| 195 |
+
FieldStorage
|
| 196 |
+
|
| 197 |
+
Returns a dictionary just like parse_qs(): keys are the field names, each
|
| 198 |
+
value is a list of values for that field. For non-file fields, the value
|
| 199 |
+
is a list of strings.
|
| 200 |
+
"""
|
| 201 |
+
# RFC 2026, Section 5.1 : The "multipart" boundary delimiters are always
|
| 202 |
+
# represented as 7bit US-ASCII.
|
| 203 |
+
boundary = pdict['boundary'].decode('ascii')
|
| 204 |
+
ctype = "multipart/form-data; boundary={}".format(boundary)
|
| 205 |
+
headers = Message()
|
| 206 |
+
headers.set_type(ctype)
|
| 207 |
+
try:
|
| 208 |
+
headers['Content-Length'] = pdict['CONTENT-LENGTH']
|
| 209 |
+
except KeyError:
|
| 210 |
+
pass
|
| 211 |
+
fs = FieldStorage(fp, headers=headers, encoding=encoding, errors=errors,
|
| 212 |
+
environ={'REQUEST_METHOD': 'POST'}, separator=separator)
|
| 213 |
+
return {k: fs.getlist(k) for k in fs}
|
| 214 |
+
|
| 215 |
+
def _parseparam(s):
|
| 216 |
+
while s[:1] == ';':
|
| 217 |
+
s = s[1:]
|
| 218 |
+
end = s.find(';')
|
| 219 |
+
while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2:
|
| 220 |
+
end = s.find(';', end + 1)
|
| 221 |
+
if end < 0:
|
| 222 |
+
end = len(s)
|
| 223 |
+
f = s[:end]
|
| 224 |
+
yield f.strip()
|
| 225 |
+
s = s[end:]
|
| 226 |
+
|
| 227 |
+
def parse_header(line):
|
| 228 |
+
"""Parse a Content-type like header.
|
| 229 |
+
|
| 230 |
+
Return the main content-type and a dictionary of options.
|
| 231 |
+
|
| 232 |
+
"""
|
| 233 |
+
parts = _parseparam(';' + line)
|
| 234 |
+
key = parts.__next__()
|
| 235 |
+
pdict = {}
|
| 236 |
+
for p in parts:
|
| 237 |
+
i = p.find('=')
|
| 238 |
+
if i >= 0:
|
| 239 |
+
name = p[:i].strip().lower()
|
| 240 |
+
value = p[i+1:].strip()
|
| 241 |
+
if len(value) >= 2 and value[0] == value[-1] == '"':
|
| 242 |
+
value = value[1:-1]
|
| 243 |
+
value = value.replace('\\\\', '\\').replace('\\"', '"')
|
| 244 |
+
pdict[name] = value
|
| 245 |
+
return key, pdict
|
| 246 |
+
|
| 247 |
+
|
| 248 |
+
# Classes for field storage
|
| 249 |
+
# =========================
|
| 250 |
+
|
| 251 |
+
class MiniFieldStorage:
|
| 252 |
+
|
| 253 |
+
"""Like FieldStorage, for use when no file uploads are possible."""
|
| 254 |
+
|
| 255 |
+
# Dummy attributes
|
| 256 |
+
filename = None
|
| 257 |
+
list = None
|
| 258 |
+
type = None
|
| 259 |
+
file = None
|
| 260 |
+
type_options = {}
|
| 261 |
+
disposition = None
|
| 262 |
+
disposition_options = {}
|
| 263 |
+
headers = {}
|
| 264 |
+
|
| 265 |
+
def __init__(self, name, value):
|
| 266 |
+
"""Constructor from field name and value."""
|
| 267 |
+
self.name = name
|
| 268 |
+
self.value = value
|
| 269 |
+
# self.file = StringIO(value)
|
| 270 |
+
|
| 271 |
+
def __repr__(self):
|
| 272 |
+
"""Return printable representation."""
|
| 273 |
+
return "MiniFieldStorage(%r, %r)" % (self.name, self.value)
|
| 274 |
+
|
| 275 |
+
|
| 276 |
+
class FieldStorage:
|
| 277 |
+
|
| 278 |
+
"""Store a sequence of fields, reading multipart/form-data.
|
| 279 |
+
|
| 280 |
+
This class provides naming, typing, files stored on disk, and
|
| 281 |
+
more. At the top level, it is accessible like a dictionary, whose
|
| 282 |
+
keys are the field names. (Note: None can occur as a field name.)
|
| 283 |
+
The items are either a Python list (if there's multiple values) or
|
| 284 |
+
another FieldStorage or MiniFieldStorage object. If it's a single
|
| 285 |
+
object, it has the following attributes:
|
| 286 |
+
|
| 287 |
+
name: the field name, if specified; otherwise None
|
| 288 |
+
|
| 289 |
+
filename: the filename, if specified; otherwise None; this is the
|
| 290 |
+
client side filename, *not* the file name on which it is
|
| 291 |
+
stored (that's a temporary file you don't deal with)
|
| 292 |
+
|
| 293 |
+
value: the value as a *string*; for file uploads, this
|
| 294 |
+
transparently reads the file every time you request the value
|
| 295 |
+
and returns *bytes*
|
| 296 |
+
|
| 297 |
+
file: the file(-like) object from which you can read the data *as
|
| 298 |
+
bytes* ; None if the data is stored a simple string
|
| 299 |
+
|
| 300 |
+
type: the content-type, or None if not specified
|
| 301 |
+
|
| 302 |
+
type_options: dictionary of options specified on the content-type
|
| 303 |
+
line
|
| 304 |
+
|
| 305 |
+
disposition: content-disposition, or None if not specified
|
| 306 |
+
|
| 307 |
+
disposition_options: dictionary of corresponding options
|
| 308 |
+
|
| 309 |
+
headers: a dictionary(-like) object (sometimes email.message.Message or a
|
| 310 |
+
subclass thereof) containing *all* headers
|
| 311 |
+
|
| 312 |
+
The class is subclassable, mostly for the purpose of overriding
|
| 313 |
+
the make_file() method, which is called internally to come up with
|
| 314 |
+
a file open for reading and writing. This makes it possible to
|
| 315 |
+
override the default choice of storing all files in a temporary
|
| 316 |
+
directory and unlinking them as soon as they have been opened.
|
| 317 |
+
|
| 318 |
+
"""
|
| 319 |
+
def __init__(self, fp=None, headers=None, outerboundary=b'',
|
| 320 |
+
environ=os.environ, keep_blank_values=0, strict_parsing=0,
|
| 321 |
+
limit=None, encoding='utf-8', errors='replace',
|
| 322 |
+
max_num_fields=None, separator='&'):
|
| 323 |
+
"""Constructor. Read multipart/* until last part.
|
| 324 |
+
|
| 325 |
+
Arguments, all optional:
|
| 326 |
+
|
| 327 |
+
fp : file pointer; default: sys.stdin.buffer
|
| 328 |
+
(not used when the request method is GET)
|
| 329 |
+
Can be :
|
| 330 |
+
1. a TextIOWrapper object
|
| 331 |
+
2. an object whose read() and readline() methods return bytes
|
| 332 |
+
|
| 333 |
+
headers : header dictionary-like object; default:
|
| 334 |
+
taken from environ as per CGI spec
|
| 335 |
+
|
| 336 |
+
outerboundary : terminating multipart boundary
|
| 337 |
+
(for internal use only)
|
| 338 |
+
|
| 339 |
+
environ : environment dictionary; default: os.environ
|
| 340 |
+
|
| 341 |
+
keep_blank_values: flag indicating whether blank values in
|
| 342 |
+
percent-encoded forms should be treated as blank strings.
|
| 343 |
+
A true value indicates that blanks should be retained as
|
| 344 |
+
blank strings. The default false value indicates that
|
| 345 |
+
blank values are to be ignored and treated as if they were
|
| 346 |
+
not included.
|
| 347 |
+
|
| 348 |
+
strict_parsing: flag indicating what to do with parsing errors.
|
| 349 |
+
If false (the default), errors are silently ignored.
|
| 350 |
+
If true, errors raise a ValueError exception.
|
| 351 |
+
|
| 352 |
+
limit : used internally to read parts of multipart/form-data forms,
|
| 353 |
+
to exit from the reading loop when reached. It is the difference
|
| 354 |
+
between the form content-length and the number of bytes already
|
| 355 |
+
read
|
| 356 |
+
|
| 357 |
+
encoding, errors : the encoding and error handler used to decode the
|
| 358 |
+
binary stream to strings. Must be the same as the charset defined
|
| 359 |
+
for the page sending the form (content-type : meta http-equiv or
|
| 360 |
+
header)
|
| 361 |
+
|
| 362 |
+
max_num_fields: int. If set, then __init__ throws a ValueError
|
| 363 |
+
if there are more than n fields read by parse_qsl().
|
| 364 |
+
|
| 365 |
+
"""
|
| 366 |
+
method = 'GET'
|
| 367 |
+
self.keep_blank_values = keep_blank_values
|
| 368 |
+
self.strict_parsing = strict_parsing
|
| 369 |
+
self.max_num_fields = max_num_fields
|
| 370 |
+
self.separator = separator
|
| 371 |
+
if 'REQUEST_METHOD' in environ:
|
| 372 |
+
method = environ['REQUEST_METHOD'].upper()
|
| 373 |
+
self.qs_on_post = None
|
| 374 |
+
if method == 'GET' or method == 'HEAD':
|
| 375 |
+
if 'QUERY_STRING' in environ:
|
| 376 |
+
qs = environ['QUERY_STRING']
|
| 377 |
+
elif sys.argv[1:]:
|
| 378 |
+
qs = sys.argv[1]
|
| 379 |
+
else:
|
| 380 |
+
qs = ""
|
| 381 |
+
qs = qs.encode(locale.getpreferredencoding(), 'surrogateescape')
|
| 382 |
+
fp = BytesIO(qs)
|
| 383 |
+
if headers is None:
|
| 384 |
+
headers = {'content-type':
|
| 385 |
+
"application/x-www-form-urlencoded"}
|
| 386 |
+
if headers is None:
|
| 387 |
+
headers = {}
|
| 388 |
+
if method == 'POST':
|
| 389 |
+
# Set default content-type for POST to what's traditional
|
| 390 |
+
headers['content-type'] = "application/x-www-form-urlencoded"
|
| 391 |
+
if 'CONTENT_TYPE' in environ:
|
| 392 |
+
headers['content-type'] = environ['CONTENT_TYPE']
|
| 393 |
+
if 'QUERY_STRING' in environ:
|
| 394 |
+
self.qs_on_post = environ['QUERY_STRING']
|
| 395 |
+
if 'CONTENT_LENGTH' in environ:
|
| 396 |
+
headers['content-length'] = environ['CONTENT_LENGTH']
|
| 397 |
+
else:
|
| 398 |
+
if not (isinstance(headers, (Mapping, Message))):
|
| 399 |
+
raise TypeError("headers must be mapping or an instance of "
|
| 400 |
+
"email.message.Message")
|
| 401 |
+
self.headers = headers
|
| 402 |
+
if fp is None:
|
| 403 |
+
self.fp = sys.stdin.buffer
|
| 404 |
+
# self.fp.read() must return bytes
|
| 405 |
+
elif isinstance(fp, TextIOWrapper):
|
| 406 |
+
self.fp = fp.buffer
|
| 407 |
+
else:
|
| 408 |
+
if not (hasattr(fp, 'read') and hasattr(fp, 'readline')):
|
| 409 |
+
raise TypeError("fp must be file pointer")
|
| 410 |
+
self.fp = fp
|
| 411 |
+
|
| 412 |
+
self.encoding = encoding
|
| 413 |
+
self.errors = errors
|
| 414 |
+
|
| 415 |
+
if not isinstance(outerboundary, bytes):
|
| 416 |
+
raise TypeError('outerboundary must be bytes, not %s'
|
| 417 |
+
% type(outerboundary).__name__)
|
| 418 |
+
self.outerboundary = outerboundary
|
| 419 |
+
|
| 420 |
+
self.bytes_read = 0
|
| 421 |
+
self.limit = limit
|
| 422 |
+
|
| 423 |
+
# Process content-disposition header
|
| 424 |
+
cdisp, pdict = "", {}
|
| 425 |
+
if 'content-disposition' in self.headers:
|
| 426 |
+
cdisp, pdict = parse_header(self.headers['content-disposition'])
|
| 427 |
+
self.disposition = cdisp
|
| 428 |
+
self.disposition_options = pdict
|
| 429 |
+
self.name = None
|
| 430 |
+
if 'name' in pdict:
|
| 431 |
+
self.name = pdict['name']
|
| 432 |
+
self.filename = None
|
| 433 |
+
if 'filename' in pdict:
|
| 434 |
+
self.filename = pdict['filename']
|
| 435 |
+
self._binary_file = self.filename is not None
|
| 436 |
+
|
| 437 |
+
# Process content-type header
|
| 438 |
+
#
|
| 439 |
+
# Honor any existing content-type header. But if there is no
|
| 440 |
+
# content-type header, use some sensible defaults. Assume
|
| 441 |
+
# outerboundary is "" at the outer level, but something non-false
|
| 442 |
+
# inside a multi-part. The default for an inner part is text/plain,
|
| 443 |
+
# but for an outer part it should be urlencoded. This should catch
|
| 444 |
+
# bogus clients which erroneously forget to include a content-type
|
| 445 |
+
# header.
|
| 446 |
+
#
|
| 447 |
+
# See below for what we do if there does exist a content-type header,
|
| 448 |
+
# but it happens to be something we don't understand.
|
| 449 |
+
if 'content-type' in self.headers:
|
| 450 |
+
ctype, pdict = parse_header(self.headers['content-type'])
|
| 451 |
+
elif self.outerboundary or method != 'POST':
|
| 452 |
+
ctype, pdict = "text/plain", {}
|
| 453 |
+
else:
|
| 454 |
+
ctype, pdict = 'application/x-www-form-urlencoded', {}
|
| 455 |
+
self.type = ctype
|
| 456 |
+
self.type_options = pdict
|
| 457 |
+
if 'boundary' in pdict:
|
| 458 |
+
self.innerboundary = pdict['boundary'].encode(self.encoding,
|
| 459 |
+
self.errors)
|
| 460 |
+
else:
|
| 461 |
+
self.innerboundary = b""
|
| 462 |
+
|
| 463 |
+
clen = -1
|
| 464 |
+
if 'content-length' in self.headers:
|
| 465 |
+
try:
|
| 466 |
+
clen = int(self.headers['content-length'])
|
| 467 |
+
except ValueError:
|
| 468 |
+
pass
|
| 469 |
+
if maxlen and clen > maxlen:
|
| 470 |
+
raise ValueError('Maximum content length exceeded')
|
| 471 |
+
self.length = clen
|
| 472 |
+
if self.limit is None and clen >= 0:
|
| 473 |
+
self.limit = clen
|
| 474 |
+
|
| 475 |
+
self.list = self.file = None
|
| 476 |
+
self.done = 0
|
| 477 |
+
if ctype == 'application/x-www-form-urlencoded':
|
| 478 |
+
self.read_urlencoded()
|
| 479 |
+
elif ctype[:10] == 'multipart/':
|
| 480 |
+
self.read_multi(environ, keep_blank_values, strict_parsing)
|
| 481 |
+
else:
|
| 482 |
+
self.read_single()
|
| 483 |
+
|
| 484 |
+
def __del__(self):
|
| 485 |
+
try:
|
| 486 |
+
self.file.close()
|
| 487 |
+
except AttributeError:
|
| 488 |
+
pass
|
| 489 |
+
|
| 490 |
+
def __enter__(self):
|
| 491 |
+
return self
|
| 492 |
+
|
| 493 |
+
def __exit__(self, *args):
|
| 494 |
+
self.file.close()
|
| 495 |
+
|
| 496 |
+
def __repr__(self):
|
| 497 |
+
"""Return a printable representation."""
|
| 498 |
+
return "FieldStorage(%r, %r, %r)" % (
|
| 499 |
+
self.name, self.filename, self.value)
|
| 500 |
+
|
| 501 |
+
def __iter__(self):
|
| 502 |
+
return iter(self.keys())
|
| 503 |
+
|
| 504 |
+
def __getattr__(self, name):
|
| 505 |
+
if name != 'value':
|
| 506 |
+
raise AttributeError(name)
|
| 507 |
+
if self.file:
|
| 508 |
+
self.file.seek(0)
|
| 509 |
+
value = self.file.read()
|
| 510 |
+
self.file.seek(0)
|
| 511 |
+
elif self.list is not None:
|
| 512 |
+
value = self.list
|
| 513 |
+
else:
|
| 514 |
+
value = None
|
| 515 |
+
return value
|
| 516 |
+
|
| 517 |
+
def __getitem__(self, key):
|
| 518 |
+
"""Dictionary style indexing."""
|
| 519 |
+
if self.list is None:
|
| 520 |
+
raise TypeError("not indexable")
|
| 521 |
+
found = []
|
| 522 |
+
for item in self.list:
|
| 523 |
+
if item.name == key: found.append(item)
|
| 524 |
+
if not found:
|
| 525 |
+
raise KeyError(key)
|
| 526 |
+
if len(found) == 1:
|
| 527 |
+
return found[0]
|
| 528 |
+
else:
|
| 529 |
+
return found
|
| 530 |
+
|
| 531 |
+
def getvalue(self, key, default=None):
|
| 532 |
+
"""Dictionary style get() method, including 'value' lookup."""
|
| 533 |
+
if key in self:
|
| 534 |
+
value = self[key]
|
| 535 |
+
if isinstance(value, list):
|
| 536 |
+
return [x.value for x in value]
|
| 537 |
+
else:
|
| 538 |
+
return value.value
|
| 539 |
+
else:
|
| 540 |
+
return default
|
| 541 |
+
|
| 542 |
+
def getfirst(self, key, default=None):
|
| 543 |
+
""" Return the first value received."""
|
| 544 |
+
if key in self:
|
| 545 |
+
value = self[key]
|
| 546 |
+
if isinstance(value, list):
|
| 547 |
+
return value[0].value
|
| 548 |
+
else:
|
| 549 |
+
return value.value
|
| 550 |
+
else:
|
| 551 |
+
return default
|
| 552 |
+
|
| 553 |
+
def getlist(self, key):
|
| 554 |
+
""" Return list of received values."""
|
| 555 |
+
if key in self:
|
| 556 |
+
value = self[key]
|
| 557 |
+
if isinstance(value, list):
|
| 558 |
+
return [x.value for x in value]
|
| 559 |
+
else:
|
| 560 |
+
return [value.value]
|
| 561 |
+
else:
|
| 562 |
+
return []
|
| 563 |
+
|
| 564 |
+
def keys(self):
|
| 565 |
+
"""Dictionary style keys() method."""
|
| 566 |
+
if self.list is None:
|
| 567 |
+
raise TypeError("not indexable")
|
| 568 |
+
return list(set(item.name for item in self.list))
|
| 569 |
+
|
| 570 |
+
def __contains__(self, key):
|
| 571 |
+
"""Dictionary style __contains__ method."""
|
| 572 |
+
if self.list is None:
|
| 573 |
+
raise TypeError("not indexable")
|
| 574 |
+
return any(item.name == key for item in self.list)
|
| 575 |
+
|
| 576 |
+
def __len__(self):
|
| 577 |
+
"""Dictionary style len(x) support."""
|
| 578 |
+
return len(self.keys())
|
| 579 |
+
|
| 580 |
+
def __bool__(self):
|
| 581 |
+
if self.list is None:
|
| 582 |
+
raise TypeError("Cannot be converted to bool.")
|
| 583 |
+
return bool(self.list)
|
| 584 |
+
|
| 585 |
+
def read_urlencoded(self):
|
| 586 |
+
"""Internal: read data in query string format."""
|
| 587 |
+
qs = self.fp.read(self.length)
|
| 588 |
+
if not isinstance(qs, bytes):
|
| 589 |
+
raise ValueError("%s should return bytes, got %s" \
|
| 590 |
+
% (self.fp, type(qs).__name__))
|
| 591 |
+
qs = qs.decode(self.encoding, self.errors)
|
| 592 |
+
if self.qs_on_post:
|
| 593 |
+
qs += '&' + self.qs_on_post
|
| 594 |
+
query = urllib.parse.parse_qsl(
|
| 595 |
+
qs, self.keep_blank_values, self.strict_parsing,
|
| 596 |
+
encoding=self.encoding, errors=self.errors,
|
| 597 |
+
max_num_fields=self.max_num_fields, separator=self.separator)
|
| 598 |
+
self.list = [MiniFieldStorage(key, value) for key, value in query]
|
| 599 |
+
self.skip_lines()
|
| 600 |
+
|
| 601 |
+
FieldStorageClass = None
|
| 602 |
+
|
| 603 |
+
def read_multi(self, environ, keep_blank_values, strict_parsing):
|
| 604 |
+
"""Internal: read a part that is itself multipart."""
|
| 605 |
+
ib = self.innerboundary
|
| 606 |
+
if not valid_boundary(ib):
|
| 607 |
+
raise ValueError('Invalid boundary in multipart form: %r' % (ib,))
|
| 608 |
+
self.list = []
|
| 609 |
+
if self.qs_on_post:
|
| 610 |
+
query = urllib.parse.parse_qsl(
|
| 611 |
+
self.qs_on_post, self.keep_blank_values, self.strict_parsing,
|
| 612 |
+
encoding=self.encoding, errors=self.errors,
|
| 613 |
+
max_num_fields=self.max_num_fields, separator=self.separator)
|
| 614 |
+
self.list.extend(MiniFieldStorage(key, value) for key, value in query)
|
| 615 |
+
|
| 616 |
+
klass = self.FieldStorageClass or self.__class__
|
| 617 |
+
first_line = self.fp.readline() # bytes
|
| 618 |
+
if not isinstance(first_line, bytes):
|
| 619 |
+
raise ValueError("%s should return bytes, got %s" \
|
| 620 |
+
% (self.fp, type(first_line).__name__))
|
| 621 |
+
self.bytes_read += len(first_line)
|
| 622 |
+
|
| 623 |
+
# Ensure that we consume the file until we've hit our inner boundary
|
| 624 |
+
while (first_line.strip() != (b"--" + self.innerboundary) and
|
| 625 |
+
first_line):
|
| 626 |
+
first_line = self.fp.readline()
|
| 627 |
+
self.bytes_read += len(first_line)
|
| 628 |
+
|
| 629 |
+
# Propagate max_num_fields into the sub class appropriately
|
| 630 |
+
max_num_fields = self.max_num_fields
|
| 631 |
+
if max_num_fields is not None:
|
| 632 |
+
max_num_fields -= len(self.list)
|
| 633 |
+
|
| 634 |
+
while True:
|
| 635 |
+
parser = FeedParser()
|
| 636 |
+
hdr_text = b""
|
| 637 |
+
while True:
|
| 638 |
+
data = self.fp.readline()
|
| 639 |
+
hdr_text += data
|
| 640 |
+
if not data.strip():
|
| 641 |
+
break
|
| 642 |
+
if not hdr_text:
|
| 643 |
+
break
|
| 644 |
+
# parser takes strings, not bytes
|
| 645 |
+
self.bytes_read += len(hdr_text)
|
| 646 |
+
parser.feed(hdr_text.decode(self.encoding, self.errors))
|
| 647 |
+
headers = parser.close()
|
| 648 |
+
|
| 649 |
+
# Some clients add Content-Length for part headers, ignore them
|
| 650 |
+
if 'content-length' in headers:
|
| 651 |
+
del headers['content-length']
|
| 652 |
+
|
| 653 |
+
limit = None if self.limit is None \
|
| 654 |
+
else self.limit - self.bytes_read
|
| 655 |
+
part = klass(self.fp, headers, ib, environ, keep_blank_values,
|
| 656 |
+
strict_parsing, limit,
|
| 657 |
+
self.encoding, self.errors, max_num_fields, self.separator)
|
| 658 |
+
|
| 659 |
+
if max_num_fields is not None:
|
| 660 |
+
max_num_fields -= 1
|
| 661 |
+
if part.list:
|
| 662 |
+
max_num_fields -= len(part.list)
|
| 663 |
+
if max_num_fields < 0:
|
| 664 |
+
raise ValueError('Max number of fields exceeded')
|
| 665 |
+
|
| 666 |
+
self.bytes_read += part.bytes_read
|
| 667 |
+
self.list.append(part)
|
| 668 |
+
if part.done or self.bytes_read >= self.length > 0:
|
| 669 |
+
break
|
| 670 |
+
self.skip_lines()
|
| 671 |
+
|
| 672 |
+
def read_single(self):
|
| 673 |
+
"""Internal: read an atomic part."""
|
| 674 |
+
if self.length >= 0:
|
| 675 |
+
self.read_binary()
|
| 676 |
+
self.skip_lines()
|
| 677 |
+
else:
|
| 678 |
+
self.read_lines()
|
| 679 |
+
self.file.seek(0)
|
| 680 |
+
|
| 681 |
+
bufsize = 8*1024 # I/O buffering size for copy to file
|
| 682 |
+
|
| 683 |
+
def read_binary(self):
|
| 684 |
+
"""Internal: read binary data."""
|
| 685 |
+
self.file = self.make_file()
|
| 686 |
+
todo = self.length
|
| 687 |
+
if todo >= 0:
|
| 688 |
+
while todo > 0:
|
| 689 |
+
data = self.fp.read(min(todo, self.bufsize)) # bytes
|
| 690 |
+
if not isinstance(data, bytes):
|
| 691 |
+
raise ValueError("%s should return bytes, got %s"
|
| 692 |
+
% (self.fp, type(data).__name__))
|
| 693 |
+
self.bytes_read += len(data)
|
| 694 |
+
if not data:
|
| 695 |
+
self.done = -1
|
| 696 |
+
break
|
| 697 |
+
self.file.write(data)
|
| 698 |
+
todo = todo - len(data)
|
| 699 |
+
|
| 700 |
+
def read_lines(self):
|
| 701 |
+
"""Internal: read lines until EOF or outerboundary."""
|
| 702 |
+
if self._binary_file:
|
| 703 |
+
self.file = self.__file = BytesIO() # store data as bytes for files
|
| 704 |
+
else:
|
| 705 |
+
self.file = self.__file = StringIO() # as strings for other fields
|
| 706 |
+
if self.outerboundary:
|
| 707 |
+
self.read_lines_to_outerboundary()
|
| 708 |
+
else:
|
| 709 |
+
self.read_lines_to_eof()
|
| 710 |
+
|
| 711 |
+
def __write(self, line):
|
| 712 |
+
"""line is always bytes, not string"""
|
| 713 |
+
if self.__file is not None:
|
| 714 |
+
if self.__file.tell() + len(line) > 1000:
|
| 715 |
+
self.file = self.make_file()
|
| 716 |
+
data = self.__file.getvalue()
|
| 717 |
+
self.file.write(data)
|
| 718 |
+
self.__file = None
|
| 719 |
+
if self._binary_file:
|
| 720 |
+
# keep bytes
|
| 721 |
+
self.file.write(line)
|
| 722 |
+
else:
|
| 723 |
+
# decode to string
|
| 724 |
+
self.file.write(line.decode(self.encoding, self.errors))
|
| 725 |
+
|
| 726 |
+
def read_lines_to_eof(self):
|
| 727 |
+
"""Internal: read lines until EOF."""
|
| 728 |
+
while 1:
|
| 729 |
+
line = self.fp.readline(1<<16) # bytes
|
| 730 |
+
self.bytes_read += len(line)
|
| 731 |
+
if not line:
|
| 732 |
+
self.done = -1
|
| 733 |
+
break
|
| 734 |
+
self.__write(line)
|
| 735 |
+
|
| 736 |
+
def read_lines_to_outerboundary(self):
|
| 737 |
+
"""Internal: read lines until outerboundary.
|
| 738 |
+
Data is read as bytes: boundaries and line ends must be converted
|
| 739 |
+
to bytes for comparisons.
|
| 740 |
+
"""
|
| 741 |
+
next_boundary = b"--" + self.outerboundary
|
| 742 |
+
last_boundary = next_boundary + b"--"
|
| 743 |
+
delim = b""
|
| 744 |
+
last_line_lfend = True
|
| 745 |
+
_read = 0
|
| 746 |
+
while 1:
|
| 747 |
+
|
| 748 |
+
if self.limit is not None and 0 <= self.limit <= _read:
|
| 749 |
+
break
|
| 750 |
+
line = self.fp.readline(1<<16) # bytes
|
| 751 |
+
self.bytes_read += len(line)
|
| 752 |
+
_read += len(line)
|
| 753 |
+
if not line:
|
| 754 |
+
self.done = -1
|
| 755 |
+
break
|
| 756 |
+
if delim == b"\r":
|
| 757 |
+
line = delim + line
|
| 758 |
+
delim = b""
|
| 759 |
+
if line.startswith(b"--") and last_line_lfend:
|
| 760 |
+
strippedline = line.rstrip()
|
| 761 |
+
if strippedline == next_boundary:
|
| 762 |
+
break
|
| 763 |
+
if strippedline == last_boundary:
|
| 764 |
+
self.done = 1
|
| 765 |
+
break
|
| 766 |
+
odelim = delim
|
| 767 |
+
if line.endswith(b"\r\n"):
|
| 768 |
+
delim = b"\r\n"
|
| 769 |
+
line = line[:-2]
|
| 770 |
+
last_line_lfend = True
|
| 771 |
+
elif line.endswith(b"\n"):
|
| 772 |
+
delim = b"\n"
|
| 773 |
+
line = line[:-1]
|
| 774 |
+
last_line_lfend = True
|
| 775 |
+
elif line.endswith(b"\r"):
|
| 776 |
+
# We may interrupt \r\n sequences if they span the 2**16
|
| 777 |
+
# byte boundary
|
| 778 |
+
delim = b"\r"
|
| 779 |
+
line = line[:-1]
|
| 780 |
+
last_line_lfend = False
|
| 781 |
+
else:
|
| 782 |
+
delim = b""
|
| 783 |
+
last_line_lfend = False
|
| 784 |
+
self.__write(odelim + line)
|
| 785 |
+
|
| 786 |
+
def skip_lines(self):
|
| 787 |
+
"""Internal: skip lines until outer boundary if defined."""
|
| 788 |
+
if not self.outerboundary or self.done:
|
| 789 |
+
return
|
| 790 |
+
next_boundary = b"--" + self.outerboundary
|
| 791 |
+
last_boundary = next_boundary + b"--"
|
| 792 |
+
last_line_lfend = True
|
| 793 |
+
while True:
|
| 794 |
+
line = self.fp.readline(1<<16)
|
| 795 |
+
self.bytes_read += len(line)
|
| 796 |
+
if not line:
|
| 797 |
+
self.done = -1
|
| 798 |
+
break
|
| 799 |
+
if line.endswith(b"--") and last_line_lfend:
|
| 800 |
+
strippedline = line.strip()
|
| 801 |
+
if strippedline == next_boundary:
|
| 802 |
+
break
|
| 803 |
+
if strippedline == last_boundary:
|
| 804 |
+
self.done = 1
|
| 805 |
+
break
|
| 806 |
+
last_line_lfend = line.endswith(b'\n')
|
| 807 |
+
|
| 808 |
+
def make_file(self):
|
| 809 |
+
"""Overridable: return a readable & writable file.
|
| 810 |
+
|
| 811 |
+
The file will be used as follows:
|
| 812 |
+
- data is written to it
|
| 813 |
+
- seek(0)
|
| 814 |
+
- data is read from it
|
| 815 |
+
|
| 816 |
+
The file is opened in binary mode for files, in text mode
|
| 817 |
+
for other fields
|
| 818 |
+
|
| 819 |
+
This version opens a temporary file for reading and writing,
|
| 820 |
+
and immediately deletes (unlinks) it. The trick (on Unix!) is
|
| 821 |
+
that the file can still be used, but it can't be opened by
|
| 822 |
+
another process, and it will automatically be deleted when it
|
| 823 |
+
is closed or when the current process terminates.
|
| 824 |
+
|
| 825 |
+
If you want a more permanent file, you derive a class which
|
| 826 |
+
overrides this method. If you want a visible temporary file
|
| 827 |
+
that is nevertheless automatically deleted when the script
|
| 828 |
+
terminates, try defining a __del__ method in a derived class
|
| 829 |
+
which unlinks the temporary files you have created.
|
| 830 |
+
|
| 831 |
+
"""
|
| 832 |
+
if self._binary_file:
|
| 833 |
+
return tempfile.TemporaryFile("wb+")
|
| 834 |
+
else:
|
| 835 |
+
return tempfile.TemporaryFile("w+",
|
| 836 |
+
encoding=self.encoding, newline = '\n')
|
| 837 |
+
|
| 838 |
+
|
| 839 |
+
# Test/debug code
|
| 840 |
+
# ===============
|
| 841 |
+
|
| 842 |
+
def test(environ=os.environ):
|
| 843 |
+
"""Robust test CGI script, usable as main program.
|
| 844 |
+
|
| 845 |
+
Write minimal HTTP headers and dump all information provided to
|
| 846 |
+
the script in HTML form.
|
| 847 |
+
|
| 848 |
+
"""
|
| 849 |
+
print("Content-type: text/html")
|
| 850 |
+
print()
|
| 851 |
+
sys.stderr = sys.stdout
|
| 852 |
+
try:
|
| 853 |
+
form = FieldStorage() # Replace with other classes to test those
|
| 854 |
+
print_directory()
|
| 855 |
+
print_arguments()
|
| 856 |
+
print_form(form)
|
| 857 |
+
print_environ(environ)
|
| 858 |
+
print_environ_usage()
|
| 859 |
+
def f():
|
| 860 |
+
exec("testing print_exception() -- <I>italics?</I>")
|
| 861 |
+
def g(f=f):
|
| 862 |
+
f()
|
| 863 |
+
print("<H3>What follows is a test, not an actual exception:</H3>")
|
| 864 |
+
g()
|
| 865 |
+
except:
|
| 866 |
+
print_exception()
|
| 867 |
+
|
| 868 |
+
print("<H1>Second try with a small maxlen...</H1>")
|
| 869 |
+
|
| 870 |
+
global maxlen
|
| 871 |
+
maxlen = 50
|
| 872 |
+
try:
|
| 873 |
+
form = FieldStorage() # Replace with other classes to test those
|
| 874 |
+
print_directory()
|
| 875 |
+
print_arguments()
|
| 876 |
+
print_form(form)
|
| 877 |
+
print_environ(environ)
|
| 878 |
+
except:
|
| 879 |
+
print_exception()
|
| 880 |
+
|
| 881 |
+
def print_exception(type=None, value=None, tb=None, limit=None):
|
| 882 |
+
if type is None:
|
| 883 |
+
type, value, tb = sys.exc_info()
|
| 884 |
+
import traceback
|
| 885 |
+
print()
|
| 886 |
+
print("<H3>Traceback (most recent call last):</H3>")
|
| 887 |
+
list = traceback.format_tb(tb, limit) + \
|
| 888 |
+
traceback.format_exception_only(type, value)
|
| 889 |
+
print("<PRE>%s<B>%s</B></PRE>" % (
|
| 890 |
+
html.escape("".join(list[:-1])),
|
| 891 |
+
html.escape(list[-1]),
|
| 892 |
+
))
|
| 893 |
+
del tb
|
| 894 |
+
|
| 895 |
+
def print_environ(environ=os.environ):
|
| 896 |
+
"""Dump the shell environment as HTML."""
|
| 897 |
+
keys = sorted(environ.keys())
|
| 898 |
+
print()
|
| 899 |
+
print("<H3>Shell Environment:</H3>")
|
| 900 |
+
print("<DL>")
|
| 901 |
+
for key in keys:
|
| 902 |
+
print("<DT>", html.escape(key), "<DD>", html.escape(environ[key]))
|
| 903 |
+
print("</DL>")
|
| 904 |
+
print()
|
| 905 |
+
|
| 906 |
+
def print_form(form):
|
| 907 |
+
"""Dump the contents of a form as HTML."""
|
| 908 |
+
keys = sorted(form.keys())
|
| 909 |
+
print()
|
| 910 |
+
print("<H3>Form Contents:</H3>")
|
| 911 |
+
if not keys:
|
| 912 |
+
print("<P>No form fields.")
|
| 913 |
+
print("<DL>")
|
| 914 |
+
for key in keys:
|
| 915 |
+
print("<DT>" + html.escape(key) + ":", end=' ')
|
| 916 |
+
value = form[key]
|
| 917 |
+
print("<i>" + html.escape(repr(type(value))) + "</i>")
|
| 918 |
+
print("<DD>" + html.escape(repr(value)))
|
| 919 |
+
print("</DL>")
|
| 920 |
+
print()
|
| 921 |
+
|
| 922 |
+
def print_directory():
|
| 923 |
+
"""Dump the current directory as HTML."""
|
| 924 |
+
print()
|
| 925 |
+
print("<H3>Current Working Directory:</H3>")
|
| 926 |
+
try:
|
| 927 |
+
pwd = os.getcwd()
|
| 928 |
+
except OSError as msg:
|
| 929 |
+
print("OSError:", html.escape(str(msg)))
|
| 930 |
+
else:
|
| 931 |
+
print(html.escape(pwd))
|
| 932 |
+
print()
|
| 933 |
+
|
| 934 |
+
def print_arguments():
|
| 935 |
+
print()
|
| 936 |
+
print("<H3>Command Line Arguments:</H3>")
|
| 937 |
+
print()
|
| 938 |
+
print(sys.argv)
|
| 939 |
+
print()
|
| 940 |
+
|
| 941 |
+
def print_environ_usage():
|
| 942 |
+
"""Dump a list of environment variables used by CGI as HTML."""
|
| 943 |
+
print("""
|
| 944 |
+
<H3>These environment variables could have been set:</H3>
|
| 945 |
+
<UL>
|
| 946 |
+
<LI>AUTH_TYPE
|
| 947 |
+
<LI>CONTENT_LENGTH
|
| 948 |
+
<LI>CONTENT_TYPE
|
| 949 |
+
<LI>DATE_GMT
|
| 950 |
+
<LI>DATE_LOCAL
|
| 951 |
+
<LI>DOCUMENT_NAME
|
| 952 |
+
<LI>DOCUMENT_ROOT
|
| 953 |
+
<LI>DOCUMENT_URI
|
| 954 |
+
<LI>GATEWAY_INTERFACE
|
| 955 |
+
<LI>LAST_MODIFIED
|
| 956 |
+
<LI>PATH
|
| 957 |
+
<LI>PATH_INFO
|
| 958 |
+
<LI>PATH_TRANSLATED
|
| 959 |
+
<LI>QUERY_STRING
|
| 960 |
+
<LI>REMOTE_ADDR
|
| 961 |
+
<LI>REMOTE_HOST
|
| 962 |
+
<LI>REMOTE_IDENT
|
| 963 |
+
<LI>REMOTE_USER
|
| 964 |
+
<LI>REQUEST_METHOD
|
| 965 |
+
<LI>SCRIPT_NAME
|
| 966 |
+
<LI>SERVER_NAME
|
| 967 |
+
<LI>SERVER_PORT
|
| 968 |
+
<LI>SERVER_PROTOCOL
|
| 969 |
+
<LI>SERVER_ROOT
|
| 970 |
+
<LI>SERVER_SOFTWARE
|
| 971 |
+
</UL>
|
| 972 |
+
In addition, HTTP headers sent by the server may be passed in the
|
| 973 |
+
environment as well. Here are some common variable names:
|
| 974 |
+
<UL>
|
| 975 |
+
<LI>HTTP_ACCEPT
|
| 976 |
+
<LI>HTTP_CONNECTION
|
| 977 |
+
<LI>HTTP_HOST
|
| 978 |
+
<LI>HTTP_PRAGMA
|
| 979 |
+
<LI>HTTP_REFERER
|
| 980 |
+
<LI>HTTP_USER_AGENT
|
| 981 |
+
</UL>
|
| 982 |
+
""")
|
| 983 |
+
|
| 984 |
+
|
| 985 |
+
# Utilities
|
| 986 |
+
# =========
|
| 987 |
+
|
| 988 |
+
def valid_boundary(s):
|
| 989 |
+
import re
|
| 990 |
+
if isinstance(s, bytes):
|
| 991 |
+
_vb_pattern = b"^[ -~]{0,200}[!-~]$"
|
| 992 |
+
else:
|
| 993 |
+
_vb_pattern = "^[ -~]{0,200}[!-~]$"
|
| 994 |
+
return re.match(_vb_pattern, s)
|
| 995 |
+
|
| 996 |
+
# Invoke mainline
|
| 997 |
+
# ===============
|
| 998 |
+
|
| 999 |
+
# Call test() when this file is run as a script (not imported as a module)
|
| 1000 |
+
if __name__ == '__main__':
|
| 1001 |
+
test()
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/cgitb.py
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""More comprehensive traceback formatting for Python scripts.
|
| 2 |
+
|
| 3 |
+
To enable this module, do:
|
| 4 |
+
|
| 5 |
+
import cgitb; cgitb.enable()
|
| 6 |
+
|
| 7 |
+
at the top of your script. The optional arguments to enable() are:
|
| 8 |
+
|
| 9 |
+
display - if true, tracebacks are displayed in the web browser
|
| 10 |
+
logdir - if set, tracebacks are written to files in this directory
|
| 11 |
+
context - number of lines of source code to show for each stack frame
|
| 12 |
+
format - 'text' or 'html' controls the output format
|
| 13 |
+
|
| 14 |
+
By default, tracebacks are displayed but not saved, the context is 5 lines
|
| 15 |
+
and the output format is 'html' (for backwards compatibility with the
|
| 16 |
+
original use of this module)
|
| 17 |
+
|
| 18 |
+
Alternatively, if you have caught an exception and want cgitb to display it
|
| 19 |
+
for you, call cgitb.handler(). The optional argument to handler() is a
|
| 20 |
+
3-item tuple (etype, evalue, etb) just like the value of sys.exc_info().
|
| 21 |
+
The default handler displays output as HTML.
|
| 22 |
+
|
| 23 |
+
"""
|
| 24 |
+
import inspect
|
| 25 |
+
import keyword
|
| 26 |
+
import linecache
|
| 27 |
+
import os
|
| 28 |
+
import pydoc
|
| 29 |
+
import sys
|
| 30 |
+
import tempfile
|
| 31 |
+
import time
|
| 32 |
+
import tokenize
|
| 33 |
+
import traceback
|
| 34 |
+
|
| 35 |
+
def reset():
|
| 36 |
+
"""Return a string that resets the CGI and browser to a known state."""
|
| 37 |
+
return '''<!--: spam
|
| 38 |
+
Content-Type: text/html
|
| 39 |
+
|
| 40 |
+
<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> -->
|
| 41 |
+
<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> --> -->
|
| 42 |
+
</font> </font> </font> </script> </object> </blockquote> </pre>
|
| 43 |
+
</table> </table> </table> </table> </table> </font> </font> </font>'''
|
| 44 |
+
|
| 45 |
+
__UNDEF__ = [] # a special sentinel object
|
| 46 |
+
def small(text):
|
| 47 |
+
if text:
|
| 48 |
+
return '<small>' + text + '</small>'
|
| 49 |
+
else:
|
| 50 |
+
return ''
|
| 51 |
+
|
| 52 |
+
def strong(text):
|
| 53 |
+
if text:
|
| 54 |
+
return '<strong>' + text + '</strong>'
|
| 55 |
+
else:
|
| 56 |
+
return ''
|
| 57 |
+
|
| 58 |
+
def grey(text):
|
| 59 |
+
if text:
|
| 60 |
+
return '<font color="#909090">' + text + '</font>'
|
| 61 |
+
else:
|
| 62 |
+
return ''
|
| 63 |
+
|
| 64 |
+
def lookup(name, frame, locals):
|
| 65 |
+
"""Find the value for a given name in the given environment."""
|
| 66 |
+
if name in locals:
|
| 67 |
+
return 'local', locals[name]
|
| 68 |
+
if name in frame.f_globals:
|
| 69 |
+
return 'global', frame.f_globals[name]
|
| 70 |
+
if '__builtins__' in frame.f_globals:
|
| 71 |
+
builtins = frame.f_globals['__builtins__']
|
| 72 |
+
if type(builtins) is type({}):
|
| 73 |
+
if name in builtins:
|
| 74 |
+
return 'builtin', builtins[name]
|
| 75 |
+
else:
|
| 76 |
+
if hasattr(builtins, name):
|
| 77 |
+
return 'builtin', getattr(builtins, name)
|
| 78 |
+
return None, __UNDEF__
|
| 79 |
+
|
| 80 |
+
def scanvars(reader, frame, locals):
|
| 81 |
+
"""Scan one logical line of Python and look up values of variables used."""
|
| 82 |
+
vars, lasttoken, parent, prefix, value = [], None, None, '', __UNDEF__
|
| 83 |
+
for ttype, token, start, end, line in tokenize.generate_tokens(reader):
|
| 84 |
+
if ttype == tokenize.NEWLINE: break
|
| 85 |
+
if ttype == tokenize.NAME and token not in keyword.kwlist:
|
| 86 |
+
if lasttoken == '.':
|
| 87 |
+
if parent is not __UNDEF__:
|
| 88 |
+
value = getattr(parent, token, __UNDEF__)
|
| 89 |
+
vars.append((prefix + token, prefix, value))
|
| 90 |
+
else:
|
| 91 |
+
where, value = lookup(token, frame, locals)
|
| 92 |
+
vars.append((token, where, value))
|
| 93 |
+
elif token == '.':
|
| 94 |
+
prefix += lasttoken + '.'
|
| 95 |
+
parent = value
|
| 96 |
+
else:
|
| 97 |
+
parent, prefix = None, ''
|
| 98 |
+
lasttoken = token
|
| 99 |
+
return vars
|
| 100 |
+
|
| 101 |
+
def html(einfo, context=5):
|
| 102 |
+
"""Return a nice HTML document describing a given traceback."""
|
| 103 |
+
etype, evalue, etb = einfo
|
| 104 |
+
if isinstance(etype, type):
|
| 105 |
+
etype = etype.__name__
|
| 106 |
+
pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
|
| 107 |
+
date = time.ctime(time.time())
|
| 108 |
+
head = '<body bgcolor="#f0f0f8">' + pydoc.html.heading(
|
| 109 |
+
'<big><big>%s</big></big>' %
|
| 110 |
+
strong(pydoc.html.escape(str(etype))),
|
| 111 |
+
'#ffffff', '#6622aa', pyver + '<br>' + date) + '''
|
| 112 |
+
<p>A problem occurred in a Python script. Here is the sequence of
|
| 113 |
+
function calls leading up to the error, in the order they occurred.</p>'''
|
| 114 |
+
|
| 115 |
+
indent = '<tt>' + small(' ' * 5) + ' </tt>'
|
| 116 |
+
frames = []
|
| 117 |
+
records = inspect.getinnerframes(etb, context)
|
| 118 |
+
for frame, file, lnum, func, lines, index in records:
|
| 119 |
+
if file:
|
| 120 |
+
file = os.path.abspath(file)
|
| 121 |
+
link = '<a href="file://%s">%s</a>' % (file, pydoc.html.escape(file))
|
| 122 |
+
else:
|
| 123 |
+
file = link = '?'
|
| 124 |
+
args, varargs, varkw, locals = inspect.getargvalues(frame)
|
| 125 |
+
call = ''
|
| 126 |
+
if func != '?':
|
| 127 |
+
call = 'in ' + strong(pydoc.html.escape(func))
|
| 128 |
+
if func != "<module>":
|
| 129 |
+
call += inspect.formatargvalues(args, varargs, varkw, locals,
|
| 130 |
+
formatvalue=lambda value: '=' + pydoc.html.repr(value))
|
| 131 |
+
|
| 132 |
+
highlight = {}
|
| 133 |
+
def reader(lnum=[lnum]):
|
| 134 |
+
highlight[lnum[0]] = 1
|
| 135 |
+
try: return linecache.getline(file, lnum[0])
|
| 136 |
+
finally: lnum[0] += 1
|
| 137 |
+
vars = scanvars(reader, frame, locals)
|
| 138 |
+
|
| 139 |
+
rows = ['<tr><td bgcolor="#d8bbff">%s%s %s</td></tr>' %
|
| 140 |
+
('<big> </big>', link, call)]
|
| 141 |
+
if index is not None:
|
| 142 |
+
i = lnum - index
|
| 143 |
+
for line in lines:
|
| 144 |
+
num = small(' ' * (5-len(str(i))) + str(i)) + ' '
|
| 145 |
+
if i in highlight:
|
| 146 |
+
line = '<tt>=>%s%s</tt>' % (num, pydoc.html.preformat(line))
|
| 147 |
+
rows.append('<tr><td bgcolor="#ffccee">%s</td></tr>' % line)
|
| 148 |
+
else:
|
| 149 |
+
line = '<tt> %s%s</tt>' % (num, pydoc.html.preformat(line))
|
| 150 |
+
rows.append('<tr><td>%s</td></tr>' % grey(line))
|
| 151 |
+
i += 1
|
| 152 |
+
|
| 153 |
+
done, dump = {}, []
|
| 154 |
+
for name, where, value in vars:
|
| 155 |
+
if name in done: continue
|
| 156 |
+
done[name] = 1
|
| 157 |
+
if value is not __UNDEF__:
|
| 158 |
+
if where in ('global', 'builtin'):
|
| 159 |
+
name = ('<em>%s</em> ' % where) + strong(name)
|
| 160 |
+
elif where == 'local':
|
| 161 |
+
name = strong(name)
|
| 162 |
+
else:
|
| 163 |
+
name = where + strong(name.split('.')[-1])
|
| 164 |
+
dump.append('%s = %s' % (name, pydoc.html.repr(value)))
|
| 165 |
+
else:
|
| 166 |
+
dump.append(name + ' <em>undefined</em>')
|
| 167 |
+
|
| 168 |
+
rows.append('<tr><td>%s</td></tr>' % small(grey(', '.join(dump))))
|
| 169 |
+
frames.append('''
|
| 170 |
+
<table width="100%%" cellspacing=0 cellpadding=0 border=0>
|
| 171 |
+
%s</table>''' % '\n'.join(rows))
|
| 172 |
+
|
| 173 |
+
exception = ['<p>%s: %s' % (strong(pydoc.html.escape(str(etype))),
|
| 174 |
+
pydoc.html.escape(str(evalue)))]
|
| 175 |
+
for name in dir(evalue):
|
| 176 |
+
if name[:1] == '_': continue
|
| 177 |
+
value = pydoc.html.repr(getattr(evalue, name))
|
| 178 |
+
exception.append('\n<br>%s%s =\n%s' % (indent, name, value))
|
| 179 |
+
|
| 180 |
+
return head + ''.join(frames) + ''.join(exception) + '''
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
<!-- The above is a description of an error in a Python program, formatted
|
| 184 |
+
for a Web browser because the 'cgitb' module was enabled. In case you
|
| 185 |
+
are not reading this in a Web browser, here is the original traceback:
|
| 186 |
+
|
| 187 |
+
%s
|
| 188 |
+
-->
|
| 189 |
+
''' % pydoc.html.escape(
|
| 190 |
+
''.join(traceback.format_exception(etype, evalue, etb)))
|
| 191 |
+
|
| 192 |
+
def text(einfo, context=5):
|
| 193 |
+
"""Return a plain text document describing a given traceback."""
|
| 194 |
+
etype, evalue, etb = einfo
|
| 195 |
+
if isinstance(etype, type):
|
| 196 |
+
etype = etype.__name__
|
| 197 |
+
pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
|
| 198 |
+
date = time.ctime(time.time())
|
| 199 |
+
head = "%s\n%s\n%s\n" % (str(etype), pyver, date) + '''
|
| 200 |
+
A problem occurred in a Python script. Here is the sequence of
|
| 201 |
+
function calls leading up to the error, in the order they occurred.
|
| 202 |
+
'''
|
| 203 |
+
|
| 204 |
+
frames = []
|
| 205 |
+
records = inspect.getinnerframes(etb, context)
|
| 206 |
+
for frame, file, lnum, func, lines, index in records:
|
| 207 |
+
file = file and os.path.abspath(file) or '?'
|
| 208 |
+
args, varargs, varkw, locals = inspect.getargvalues(frame)
|
| 209 |
+
call = ''
|
| 210 |
+
if func != '?':
|
| 211 |
+
call = 'in ' + func
|
| 212 |
+
if func != "<module>":
|
| 213 |
+
call += inspect.formatargvalues(args, varargs, varkw, locals,
|
| 214 |
+
formatvalue=lambda value: '=' + pydoc.text.repr(value))
|
| 215 |
+
|
| 216 |
+
highlight = {}
|
| 217 |
+
def reader(lnum=[lnum]):
|
| 218 |
+
highlight[lnum[0]] = 1
|
| 219 |
+
try: return linecache.getline(file, lnum[0])
|
| 220 |
+
finally: lnum[0] += 1
|
| 221 |
+
vars = scanvars(reader, frame, locals)
|
| 222 |
+
|
| 223 |
+
rows = [' %s %s' % (file, call)]
|
| 224 |
+
if index is not None:
|
| 225 |
+
i = lnum - index
|
| 226 |
+
for line in lines:
|
| 227 |
+
num = '%5d ' % i
|
| 228 |
+
rows.append(num+line.rstrip())
|
| 229 |
+
i += 1
|
| 230 |
+
|
| 231 |
+
done, dump = {}, []
|
| 232 |
+
for name, where, value in vars:
|
| 233 |
+
if name in done: continue
|
| 234 |
+
done[name] = 1
|
| 235 |
+
if value is not __UNDEF__:
|
| 236 |
+
if where == 'global': name = 'global ' + name
|
| 237 |
+
elif where != 'local': name = where + name.split('.')[-1]
|
| 238 |
+
dump.append('%s = %s' % (name, pydoc.text.repr(value)))
|
| 239 |
+
else:
|
| 240 |
+
dump.append(name + ' undefined')
|
| 241 |
+
|
| 242 |
+
rows.append('\n'.join(dump))
|
| 243 |
+
frames.append('\n%s\n' % '\n'.join(rows))
|
| 244 |
+
|
| 245 |
+
exception = ['%s: %s' % (str(etype), str(evalue))]
|
| 246 |
+
for name in dir(evalue):
|
| 247 |
+
value = pydoc.text.repr(getattr(evalue, name))
|
| 248 |
+
exception.append('\n%s%s = %s' % (" "*4, name, value))
|
| 249 |
+
|
| 250 |
+
return head + ''.join(frames) + ''.join(exception) + '''
|
| 251 |
+
|
| 252 |
+
The above is a description of an error in a Python program. Here is
|
| 253 |
+
the original traceback:
|
| 254 |
+
|
| 255 |
+
%s
|
| 256 |
+
''' % ''.join(traceback.format_exception(etype, evalue, etb))
|
| 257 |
+
|
| 258 |
+
class Hook:
|
| 259 |
+
"""A hook to replace sys.excepthook that shows tracebacks in HTML."""
|
| 260 |
+
|
| 261 |
+
def __init__(self, display=1, logdir=None, context=5, file=None,
|
| 262 |
+
format="html"):
|
| 263 |
+
self.display = display # send tracebacks to browser if true
|
| 264 |
+
self.logdir = logdir # log tracebacks to files if not None
|
| 265 |
+
self.context = context # number of source code lines per frame
|
| 266 |
+
self.file = file or sys.stdout # place to send the output
|
| 267 |
+
self.format = format
|
| 268 |
+
|
| 269 |
+
def __call__(self, etype, evalue, etb):
|
| 270 |
+
self.handle((etype, evalue, etb))
|
| 271 |
+
|
| 272 |
+
def handle(self, info=None):
|
| 273 |
+
info = info or sys.exc_info()
|
| 274 |
+
if self.format == "html":
|
| 275 |
+
self.file.write(reset())
|
| 276 |
+
|
| 277 |
+
formatter = (self.format=="html") and html or text
|
| 278 |
+
plain = False
|
| 279 |
+
try:
|
| 280 |
+
doc = formatter(info, self.context)
|
| 281 |
+
except: # just in case something goes wrong
|
| 282 |
+
doc = ''.join(traceback.format_exception(*info))
|
| 283 |
+
plain = True
|
| 284 |
+
|
| 285 |
+
if self.display:
|
| 286 |
+
if plain:
|
| 287 |
+
doc = pydoc.html.escape(doc)
|
| 288 |
+
self.file.write('<pre>' + doc + '</pre>\n')
|
| 289 |
+
else:
|
| 290 |
+
self.file.write(doc + '\n')
|
| 291 |
+
else:
|
| 292 |
+
self.file.write('<p>A problem occurred in a Python script.\n')
|
| 293 |
+
|
| 294 |
+
if self.logdir is not None:
|
| 295 |
+
suffix = ['.txt', '.html'][self.format=="html"]
|
| 296 |
+
(fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir)
|
| 297 |
+
|
| 298 |
+
try:
|
| 299 |
+
with os.fdopen(fd, 'w') as file:
|
| 300 |
+
file.write(doc)
|
| 301 |
+
msg = '%s contains the description of this error.' % path
|
| 302 |
+
except:
|
| 303 |
+
msg = 'Tried to save traceback to %s, but failed.' % path
|
| 304 |
+
|
| 305 |
+
if self.format == 'html':
|
| 306 |
+
self.file.write('<p>%s</p>\n' % msg)
|
| 307 |
+
else:
|
| 308 |
+
self.file.write(msg + '\n')
|
| 309 |
+
try:
|
| 310 |
+
self.file.flush()
|
| 311 |
+
except: pass
|
| 312 |
+
|
| 313 |
+
handler = Hook().handle
|
| 314 |
+
def enable(display=1, logdir=None, context=5, format="html"):
|
| 315 |
+
"""Install an exception handler that formats tracebacks as HTML.
|
| 316 |
+
|
| 317 |
+
The optional argument 'display' can be set to 0 to suppress sending the
|
| 318 |
+
traceback to the browser, and 'logdir' can be set to a directory to cause
|
| 319 |
+
tracebacks to be written to files there."""
|
| 320 |
+
sys.excepthook = Hook(display=display, logdir=logdir,
|
| 321 |
+
context=context, format=format)
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/code.py
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Utilities needed to emulate Python's interactive interpreter.
|
| 2 |
+
|
| 3 |
+
"""
|
| 4 |
+
|
| 5 |
+
# Inspired by similar code by Jeff Epler and Fredrik Lundh.
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
import sys
|
| 9 |
+
import traceback
|
| 10 |
+
from codeop import CommandCompiler, compile_command
|
| 11 |
+
|
| 12 |
+
__all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact",
|
| 13 |
+
"compile_command"]
|
| 14 |
+
|
| 15 |
+
class InteractiveInterpreter:
|
| 16 |
+
"""Base class for InteractiveConsole.
|
| 17 |
+
|
| 18 |
+
This class deals with parsing and interpreter state (the user's
|
| 19 |
+
namespace); it doesn't deal with input buffering or prompting or
|
| 20 |
+
input file naming (the filename is always passed in explicitly).
|
| 21 |
+
|
| 22 |
+
"""
|
| 23 |
+
|
| 24 |
+
def __init__(self, locals=None):
|
| 25 |
+
"""Constructor.
|
| 26 |
+
|
| 27 |
+
The optional 'locals' argument specifies the dictionary in
|
| 28 |
+
which code will be executed; it defaults to a newly created
|
| 29 |
+
dictionary with key "__name__" set to "__console__" and key
|
| 30 |
+
"__doc__" set to None.
|
| 31 |
+
|
| 32 |
+
"""
|
| 33 |
+
if locals is None:
|
| 34 |
+
locals = {"__name__": "__console__", "__doc__": None}
|
| 35 |
+
self.locals = locals
|
| 36 |
+
self.compile = CommandCompiler()
|
| 37 |
+
|
| 38 |
+
def runsource(self, source, filename="<input>", symbol="single"):
|
| 39 |
+
"""Compile and run some source in the interpreter.
|
| 40 |
+
|
| 41 |
+
Arguments are as for compile_command().
|
| 42 |
+
|
| 43 |
+
One of several things can happen:
|
| 44 |
+
|
| 45 |
+
1) The input is incorrect; compile_command() raised an
|
| 46 |
+
exception (SyntaxError or OverflowError). A syntax traceback
|
| 47 |
+
will be printed by calling the showsyntaxerror() method.
|
| 48 |
+
|
| 49 |
+
2) The input is incomplete, and more input is required;
|
| 50 |
+
compile_command() returned None. Nothing happens.
|
| 51 |
+
|
| 52 |
+
3) The input is complete; compile_command() returned a code
|
| 53 |
+
object. The code is executed by calling self.runcode() (which
|
| 54 |
+
also handles run-time exceptions, except for SystemExit).
|
| 55 |
+
|
| 56 |
+
The return value is True in case 2, False in the other cases (unless
|
| 57 |
+
an exception is raised). The return value can be used to
|
| 58 |
+
decide whether to use sys.ps1 or sys.ps2 to prompt the next
|
| 59 |
+
line.
|
| 60 |
+
|
| 61 |
+
"""
|
| 62 |
+
try:
|
| 63 |
+
code = self.compile(source, filename, symbol)
|
| 64 |
+
except (OverflowError, SyntaxError, ValueError):
|
| 65 |
+
# Case 1
|
| 66 |
+
self.showsyntaxerror(filename)
|
| 67 |
+
return False
|
| 68 |
+
|
| 69 |
+
if code is None:
|
| 70 |
+
# Case 2
|
| 71 |
+
return True
|
| 72 |
+
|
| 73 |
+
# Case 3
|
| 74 |
+
self.runcode(code)
|
| 75 |
+
return False
|
| 76 |
+
|
| 77 |
+
def runcode(self, code):
|
| 78 |
+
"""Execute a code object.
|
| 79 |
+
|
| 80 |
+
When an exception occurs, self.showtraceback() is called to
|
| 81 |
+
display a traceback. All exceptions are caught except
|
| 82 |
+
SystemExit, which is reraised.
|
| 83 |
+
|
| 84 |
+
A note about KeyboardInterrupt: this exception may occur
|
| 85 |
+
elsewhere in this code, and may not always be caught. The
|
| 86 |
+
caller should be prepared to deal with it.
|
| 87 |
+
|
| 88 |
+
"""
|
| 89 |
+
try:
|
| 90 |
+
exec(code, self.locals)
|
| 91 |
+
except SystemExit:
|
| 92 |
+
raise
|
| 93 |
+
except:
|
| 94 |
+
self.showtraceback()
|
| 95 |
+
|
| 96 |
+
def showsyntaxerror(self, filename=None):
|
| 97 |
+
"""Display the syntax error that just occurred.
|
| 98 |
+
|
| 99 |
+
This doesn't display a stack trace because there isn't one.
|
| 100 |
+
|
| 101 |
+
If a filename is given, it is stuffed in the exception instead
|
| 102 |
+
of what was there before (because Python's parser always uses
|
| 103 |
+
"<string>" when reading from a string).
|
| 104 |
+
|
| 105 |
+
The output is written by self.write(), below.
|
| 106 |
+
|
| 107 |
+
"""
|
| 108 |
+
type, value, tb = sys.exc_info()
|
| 109 |
+
sys.last_type = type
|
| 110 |
+
sys.last_value = value
|
| 111 |
+
sys.last_traceback = tb
|
| 112 |
+
if filename and type is SyntaxError:
|
| 113 |
+
# Work hard to stuff the correct filename in the exception
|
| 114 |
+
try:
|
| 115 |
+
msg, (dummy_filename, lineno, offset, line) = value.args
|
| 116 |
+
except ValueError:
|
| 117 |
+
# Not the format we expect; leave it alone
|
| 118 |
+
pass
|
| 119 |
+
else:
|
| 120 |
+
# Stuff in the right filename
|
| 121 |
+
value = SyntaxError(msg, (filename, lineno, offset, line))
|
| 122 |
+
sys.last_value = value
|
| 123 |
+
if sys.excepthook is sys.__excepthook__:
|
| 124 |
+
lines = traceback.format_exception_only(type, value)
|
| 125 |
+
self.write(''.join(lines))
|
| 126 |
+
else:
|
| 127 |
+
# If someone has set sys.excepthook, we let that take precedence
|
| 128 |
+
# over self.write
|
| 129 |
+
sys.excepthook(type, value, tb)
|
| 130 |
+
|
| 131 |
+
def showtraceback(self):
|
| 132 |
+
"""Display the exception that just occurred.
|
| 133 |
+
|
| 134 |
+
We remove the first stack item because it is our own code.
|
| 135 |
+
|
| 136 |
+
The output is written by self.write(), below.
|
| 137 |
+
|
| 138 |
+
"""
|
| 139 |
+
sys.last_type, sys.last_value, last_tb = ei = sys.exc_info()
|
| 140 |
+
sys.last_traceback = last_tb
|
| 141 |
+
try:
|
| 142 |
+
lines = traceback.format_exception(ei[0], ei[1], last_tb.tb_next)
|
| 143 |
+
if sys.excepthook is sys.__excepthook__:
|
| 144 |
+
self.write(''.join(lines))
|
| 145 |
+
else:
|
| 146 |
+
# If someone has set sys.excepthook, we let that take precedence
|
| 147 |
+
# over self.write
|
| 148 |
+
sys.excepthook(ei[0], ei[1], last_tb)
|
| 149 |
+
finally:
|
| 150 |
+
last_tb = ei = None
|
| 151 |
+
|
| 152 |
+
def write(self, data):
|
| 153 |
+
"""Write a string.
|
| 154 |
+
|
| 155 |
+
The base implementation writes to sys.stderr; a subclass may
|
| 156 |
+
replace this with a different implementation.
|
| 157 |
+
|
| 158 |
+
"""
|
| 159 |
+
sys.stderr.write(data)
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
class InteractiveConsole(InteractiveInterpreter):
|
| 163 |
+
"""Closely emulate the behavior of the interactive Python interpreter.
|
| 164 |
+
|
| 165 |
+
This class builds on InteractiveInterpreter and adds prompting
|
| 166 |
+
using the familiar sys.ps1 and sys.ps2, and input buffering.
|
| 167 |
+
|
| 168 |
+
"""
|
| 169 |
+
|
| 170 |
+
def __init__(self, locals=None, filename="<console>"):
|
| 171 |
+
"""Constructor.
|
| 172 |
+
|
| 173 |
+
The optional locals argument will be passed to the
|
| 174 |
+
InteractiveInterpreter base class.
|
| 175 |
+
|
| 176 |
+
The optional filename argument should specify the (file)name
|
| 177 |
+
of the input stream; it will show up in tracebacks.
|
| 178 |
+
|
| 179 |
+
"""
|
| 180 |
+
InteractiveInterpreter.__init__(self, locals)
|
| 181 |
+
self.filename = filename
|
| 182 |
+
self.resetbuffer()
|
| 183 |
+
|
| 184 |
+
def resetbuffer(self):
|
| 185 |
+
"""Reset the input buffer."""
|
| 186 |
+
self.buffer = []
|
| 187 |
+
|
| 188 |
+
def interact(self, banner=None, exitmsg=None):
|
| 189 |
+
"""Closely emulate the interactive Python console.
|
| 190 |
+
|
| 191 |
+
The optional banner argument specifies the banner to print
|
| 192 |
+
before the first interaction; by default it prints a banner
|
| 193 |
+
similar to the one printed by the real Python interpreter,
|
| 194 |
+
followed by the current class name in parentheses (so as not
|
| 195 |
+
to confuse this with the real interpreter -- since it's so
|
| 196 |
+
close!).
|
| 197 |
+
|
| 198 |
+
The optional exitmsg argument specifies the exit message
|
| 199 |
+
printed when exiting. Pass the empty string to suppress
|
| 200 |
+
printing an exit message. If exitmsg is not given or None,
|
| 201 |
+
a default message is printed.
|
| 202 |
+
|
| 203 |
+
"""
|
| 204 |
+
try:
|
| 205 |
+
sys.ps1
|
| 206 |
+
except AttributeError:
|
| 207 |
+
sys.ps1 = ">>> "
|
| 208 |
+
try:
|
| 209 |
+
sys.ps2
|
| 210 |
+
except AttributeError:
|
| 211 |
+
sys.ps2 = "... "
|
| 212 |
+
cprt = 'Type "help", "copyright", "credits" or "license" for more information.'
|
| 213 |
+
if banner is None:
|
| 214 |
+
self.write("Python %s on %s\n%s\n(%s)\n" %
|
| 215 |
+
(sys.version, sys.platform, cprt,
|
| 216 |
+
self.__class__.__name__))
|
| 217 |
+
elif banner:
|
| 218 |
+
self.write("%s\n" % str(banner))
|
| 219 |
+
more = 0
|
| 220 |
+
while 1:
|
| 221 |
+
try:
|
| 222 |
+
if more:
|
| 223 |
+
prompt = sys.ps2
|
| 224 |
+
else:
|
| 225 |
+
prompt = sys.ps1
|
| 226 |
+
try:
|
| 227 |
+
line = self.raw_input(prompt)
|
| 228 |
+
except EOFError:
|
| 229 |
+
self.write("\n")
|
| 230 |
+
break
|
| 231 |
+
else:
|
| 232 |
+
more = self.push(line)
|
| 233 |
+
except KeyboardInterrupt:
|
| 234 |
+
self.write("\nKeyboardInterrupt\n")
|
| 235 |
+
self.resetbuffer()
|
| 236 |
+
more = 0
|
| 237 |
+
if exitmsg is None:
|
| 238 |
+
self.write('now exiting %s...\n' % self.__class__.__name__)
|
| 239 |
+
elif exitmsg != '':
|
| 240 |
+
self.write('%s\n' % exitmsg)
|
| 241 |
+
|
| 242 |
+
def push(self, line):
|
| 243 |
+
"""Push a line to the interpreter.
|
| 244 |
+
|
| 245 |
+
The line should not have a trailing newline; it may have
|
| 246 |
+
internal newlines. The line is appended to a buffer and the
|
| 247 |
+
interpreter's runsource() method is called with the
|
| 248 |
+
concatenated contents of the buffer as source. If this
|
| 249 |
+
indicates that the command was executed or invalid, the buffer
|
| 250 |
+
is reset; otherwise, the command is incomplete, and the buffer
|
| 251 |
+
is left as it was after the line was appended. The return
|
| 252 |
+
value is 1 if more input is required, 0 if the line was dealt
|
| 253 |
+
with in some way (this is the same as runsource()).
|
| 254 |
+
|
| 255 |
+
"""
|
| 256 |
+
self.buffer.append(line)
|
| 257 |
+
source = "\n".join(self.buffer)
|
| 258 |
+
more = self.runsource(source, self.filename)
|
| 259 |
+
if not more:
|
| 260 |
+
self.resetbuffer()
|
| 261 |
+
return more
|
| 262 |
+
|
| 263 |
+
def raw_input(self, prompt=""):
|
| 264 |
+
"""Write a prompt and read a line.
|
| 265 |
+
|
| 266 |
+
The returned line does not include the trailing newline.
|
| 267 |
+
When the user enters the EOF key sequence, EOFError is raised.
|
| 268 |
+
|
| 269 |
+
The base implementation uses the built-in function
|
| 270 |
+
input(); a subclass may replace this with a different
|
| 271 |
+
implementation.
|
| 272 |
+
|
| 273 |
+
"""
|
| 274 |
+
return input(prompt)
|
| 275 |
+
|
| 276 |
+
|
| 277 |
+
|
| 278 |
+
def interact(banner=None, readfunc=None, local=None, exitmsg=None):
|
| 279 |
+
"""Closely emulate the interactive Python interpreter.
|
| 280 |
+
|
| 281 |
+
This is a backwards compatible interface to the InteractiveConsole
|
| 282 |
+
class. When readfunc is not specified, it attempts to import the
|
| 283 |
+
readline module to enable GNU readline if it is available.
|
| 284 |
+
|
| 285 |
+
Arguments (all optional, all default to None):
|
| 286 |
+
|
| 287 |
+
banner -- passed to InteractiveConsole.interact()
|
| 288 |
+
readfunc -- if not None, replaces InteractiveConsole.raw_input()
|
| 289 |
+
local -- passed to InteractiveInterpreter.__init__()
|
| 290 |
+
exitmsg -- passed to InteractiveConsole.interact()
|
| 291 |
+
|
| 292 |
+
"""
|
| 293 |
+
console = InteractiveConsole(local)
|
| 294 |
+
if readfunc is not None:
|
| 295 |
+
console.raw_input = readfunc
|
| 296 |
+
else:
|
| 297 |
+
try:
|
| 298 |
+
import readline
|
| 299 |
+
except ImportError:
|
| 300 |
+
pass
|
| 301 |
+
console.interact(banner, exitmsg)
|
| 302 |
+
|
| 303 |
+
|
| 304 |
+
if __name__ == "__main__":
|
| 305 |
+
import argparse
|
| 306 |
+
|
| 307 |
+
parser = argparse.ArgumentParser()
|
| 308 |
+
parser.add_argument('-q', action='store_true',
|
| 309 |
+
help="don't print version and copyright messages")
|
| 310 |
+
args = parser.parse_args()
|
| 311 |
+
if args.q or sys.flags.quiet:
|
| 312 |
+
banner = ''
|
| 313 |
+
else:
|
| 314 |
+
banner = None
|
| 315 |
+
interact(banner)
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/codecs.py
ADDED
|
@@ -0,0 +1,1126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
""" codecs -- Python Codec Registry, API and helpers.
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
Written by Marc-Andre Lemburg (mal@lemburg.com).
|
| 5 |
+
|
| 6 |
+
(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
|
| 7 |
+
|
| 8 |
+
"""
|
| 9 |
+
|
| 10 |
+
import builtins
|
| 11 |
+
import sys
|
| 12 |
+
|
| 13 |
+
### Registry and builtin stateless codec functions
|
| 14 |
+
|
| 15 |
+
try:
|
| 16 |
+
from _codecs import *
|
| 17 |
+
except ImportError as why:
|
| 18 |
+
raise SystemError('Failed to load the builtin codecs: %s' % why)
|
| 19 |
+
|
| 20 |
+
__all__ = ["register", "lookup", "open", "EncodedFile", "BOM", "BOM_BE",
|
| 21 |
+
"BOM_LE", "BOM32_BE", "BOM32_LE", "BOM64_BE", "BOM64_LE",
|
| 22 |
+
"BOM_UTF8", "BOM_UTF16", "BOM_UTF16_LE", "BOM_UTF16_BE",
|
| 23 |
+
"BOM_UTF32", "BOM_UTF32_LE", "BOM_UTF32_BE",
|
| 24 |
+
"CodecInfo", "Codec", "IncrementalEncoder", "IncrementalDecoder",
|
| 25 |
+
"StreamReader", "StreamWriter",
|
| 26 |
+
"StreamReaderWriter", "StreamRecoder",
|
| 27 |
+
"getencoder", "getdecoder", "getincrementalencoder",
|
| 28 |
+
"getincrementaldecoder", "getreader", "getwriter",
|
| 29 |
+
"encode", "decode", "iterencode", "iterdecode",
|
| 30 |
+
"strict_errors", "ignore_errors", "replace_errors",
|
| 31 |
+
"xmlcharrefreplace_errors",
|
| 32 |
+
"backslashreplace_errors", "namereplace_errors",
|
| 33 |
+
"register_error", "lookup_error"]
|
| 34 |
+
|
| 35 |
+
### Constants
|
| 36 |
+
|
| 37 |
+
#
|
| 38 |
+
# Byte Order Mark (BOM = ZERO WIDTH NO-BREAK SPACE = U+FEFF)
|
| 39 |
+
# and its possible byte string values
|
| 40 |
+
# for UTF8/UTF16/UTF32 output and little/big endian machines
|
| 41 |
+
#
|
| 42 |
+
|
| 43 |
+
# UTF-8
|
| 44 |
+
BOM_UTF8 = b'\xef\xbb\xbf'
|
| 45 |
+
|
| 46 |
+
# UTF-16, little endian
|
| 47 |
+
BOM_LE = BOM_UTF16_LE = b'\xff\xfe'
|
| 48 |
+
|
| 49 |
+
# UTF-16, big endian
|
| 50 |
+
BOM_BE = BOM_UTF16_BE = b'\xfe\xff'
|
| 51 |
+
|
| 52 |
+
# UTF-32, little endian
|
| 53 |
+
BOM_UTF32_LE = b'\xff\xfe\x00\x00'
|
| 54 |
+
|
| 55 |
+
# UTF-32, big endian
|
| 56 |
+
BOM_UTF32_BE = b'\x00\x00\xfe\xff'
|
| 57 |
+
|
| 58 |
+
if sys.byteorder == 'little':
|
| 59 |
+
|
| 60 |
+
# UTF-16, native endianness
|
| 61 |
+
BOM = BOM_UTF16 = BOM_UTF16_LE
|
| 62 |
+
|
| 63 |
+
# UTF-32, native endianness
|
| 64 |
+
BOM_UTF32 = BOM_UTF32_LE
|
| 65 |
+
|
| 66 |
+
else:
|
| 67 |
+
|
| 68 |
+
# UTF-16, native endianness
|
| 69 |
+
BOM = BOM_UTF16 = BOM_UTF16_BE
|
| 70 |
+
|
| 71 |
+
# UTF-32, native endianness
|
| 72 |
+
BOM_UTF32 = BOM_UTF32_BE
|
| 73 |
+
|
| 74 |
+
# Old broken names (don't use in new code)
|
| 75 |
+
BOM32_LE = BOM_UTF16_LE
|
| 76 |
+
BOM32_BE = BOM_UTF16_BE
|
| 77 |
+
BOM64_LE = BOM_UTF32_LE
|
| 78 |
+
BOM64_BE = BOM_UTF32_BE
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
### Codec base classes (defining the API)
|
| 82 |
+
|
| 83 |
+
class CodecInfo(tuple):
|
| 84 |
+
"""Codec details when looking up the codec registry"""
|
| 85 |
+
|
| 86 |
+
# Private API to allow Python 3.4 to blacklist the known non-Unicode
|
| 87 |
+
# codecs in the standard library. A more general mechanism to
|
| 88 |
+
# reliably distinguish test encodings from other codecs will hopefully
|
| 89 |
+
# be defined for Python 3.5
|
| 90 |
+
#
|
| 91 |
+
# See http://bugs.python.org/issue19619
|
| 92 |
+
_is_text_encoding = True # Assume codecs are text encodings by default
|
| 93 |
+
|
| 94 |
+
def __new__(cls, encode, decode, streamreader=None, streamwriter=None,
|
| 95 |
+
incrementalencoder=None, incrementaldecoder=None, name=None,
|
| 96 |
+
*, _is_text_encoding=None):
|
| 97 |
+
self = tuple.__new__(cls, (encode, decode, streamreader, streamwriter))
|
| 98 |
+
self.name = name
|
| 99 |
+
self.encode = encode
|
| 100 |
+
self.decode = decode
|
| 101 |
+
self.incrementalencoder = incrementalencoder
|
| 102 |
+
self.incrementaldecoder = incrementaldecoder
|
| 103 |
+
self.streamwriter = streamwriter
|
| 104 |
+
self.streamreader = streamreader
|
| 105 |
+
if _is_text_encoding is not None:
|
| 106 |
+
self._is_text_encoding = _is_text_encoding
|
| 107 |
+
return self
|
| 108 |
+
|
| 109 |
+
def __repr__(self):
|
| 110 |
+
return "<%s.%s object for encoding %s at %#x>" % \
|
| 111 |
+
(self.__class__.__module__, self.__class__.__qualname__,
|
| 112 |
+
self.name, id(self))
|
| 113 |
+
|
| 114 |
+
class Codec:
|
| 115 |
+
|
| 116 |
+
""" Defines the interface for stateless encoders/decoders.
|
| 117 |
+
|
| 118 |
+
The .encode()/.decode() methods may use different error
|
| 119 |
+
handling schemes by providing the errors argument. These
|
| 120 |
+
string values are predefined:
|
| 121 |
+
|
| 122 |
+
'strict' - raise a ValueError error (or a subclass)
|
| 123 |
+
'ignore' - ignore the character and continue with the next
|
| 124 |
+
'replace' - replace with a suitable replacement character;
|
| 125 |
+
Python will use the official U+FFFD REPLACEMENT
|
| 126 |
+
CHARACTER for the builtin Unicode codecs on
|
| 127 |
+
decoding and '?' on encoding.
|
| 128 |
+
'surrogateescape' - replace with private code points U+DCnn.
|
| 129 |
+
'xmlcharrefreplace' - Replace with the appropriate XML
|
| 130 |
+
character reference (only for encoding).
|
| 131 |
+
'backslashreplace' - Replace with backslashed escape sequences.
|
| 132 |
+
'namereplace' - Replace with \\N{...} escape sequences
|
| 133 |
+
(only for encoding).
|
| 134 |
+
|
| 135 |
+
The set of allowed values can be extended via register_error.
|
| 136 |
+
|
| 137 |
+
"""
|
| 138 |
+
def encode(self, input, errors='strict'):
|
| 139 |
+
|
| 140 |
+
""" Encodes the object input and returns a tuple (output
|
| 141 |
+
object, length consumed).
|
| 142 |
+
|
| 143 |
+
errors defines the error handling to apply. It defaults to
|
| 144 |
+
'strict' handling.
|
| 145 |
+
|
| 146 |
+
The method may not store state in the Codec instance. Use
|
| 147 |
+
StreamWriter for codecs which have to keep state in order to
|
| 148 |
+
make encoding efficient.
|
| 149 |
+
|
| 150 |
+
The encoder must be able to handle zero length input and
|
| 151 |
+
return an empty object of the output object type in this
|
| 152 |
+
situation.
|
| 153 |
+
|
| 154 |
+
"""
|
| 155 |
+
raise NotImplementedError
|
| 156 |
+
|
| 157 |
+
def decode(self, input, errors='strict'):
|
| 158 |
+
|
| 159 |
+
""" Decodes the object input and returns a tuple (output
|
| 160 |
+
object, length consumed).
|
| 161 |
+
|
| 162 |
+
input must be an object which provides the bf_getreadbuf
|
| 163 |
+
buffer slot. Python strings, buffer objects and memory
|
| 164 |
+
mapped files are examples of objects providing this slot.
|
| 165 |
+
|
| 166 |
+
errors defines the error handling to apply. It defaults to
|
| 167 |
+
'strict' handling.
|
| 168 |
+
|
| 169 |
+
The method may not store state in the Codec instance. Use
|
| 170 |
+
StreamReader for codecs which have to keep state in order to
|
| 171 |
+
make decoding efficient.
|
| 172 |
+
|
| 173 |
+
The decoder must be able to handle zero length input and
|
| 174 |
+
return an empty object of the output object type in this
|
| 175 |
+
situation.
|
| 176 |
+
|
| 177 |
+
"""
|
| 178 |
+
raise NotImplementedError
|
| 179 |
+
|
| 180 |
+
class IncrementalEncoder(object):
|
| 181 |
+
"""
|
| 182 |
+
An IncrementalEncoder encodes an input in multiple steps. The input can
|
| 183 |
+
be passed piece by piece to the encode() method. The IncrementalEncoder
|
| 184 |
+
remembers the state of the encoding process between calls to encode().
|
| 185 |
+
"""
|
| 186 |
+
def __init__(self, errors='strict'):
|
| 187 |
+
"""
|
| 188 |
+
Creates an IncrementalEncoder instance.
|
| 189 |
+
|
| 190 |
+
The IncrementalEncoder may use different error handling schemes by
|
| 191 |
+
providing the errors keyword argument. See the module docstring
|
| 192 |
+
for a list of possible values.
|
| 193 |
+
"""
|
| 194 |
+
self.errors = errors
|
| 195 |
+
self.buffer = ""
|
| 196 |
+
|
| 197 |
+
def encode(self, input, final=False):
|
| 198 |
+
"""
|
| 199 |
+
Encodes input and returns the resulting object.
|
| 200 |
+
"""
|
| 201 |
+
raise NotImplementedError
|
| 202 |
+
|
| 203 |
+
def reset(self):
|
| 204 |
+
"""
|
| 205 |
+
Resets the encoder to the initial state.
|
| 206 |
+
"""
|
| 207 |
+
|
| 208 |
+
def getstate(self):
|
| 209 |
+
"""
|
| 210 |
+
Return the current state of the encoder.
|
| 211 |
+
"""
|
| 212 |
+
return 0
|
| 213 |
+
|
| 214 |
+
def setstate(self, state):
|
| 215 |
+
"""
|
| 216 |
+
Set the current state of the encoder. state must have been
|
| 217 |
+
returned by getstate().
|
| 218 |
+
"""
|
| 219 |
+
|
| 220 |
+
class BufferedIncrementalEncoder(IncrementalEncoder):
|
| 221 |
+
"""
|
| 222 |
+
This subclass of IncrementalEncoder can be used as the baseclass for an
|
| 223 |
+
incremental encoder if the encoder must keep some of the output in a
|
| 224 |
+
buffer between calls to encode().
|
| 225 |
+
"""
|
| 226 |
+
def __init__(self, errors='strict'):
|
| 227 |
+
IncrementalEncoder.__init__(self, errors)
|
| 228 |
+
# unencoded input that is kept between calls to encode()
|
| 229 |
+
self.buffer = ""
|
| 230 |
+
|
| 231 |
+
def _buffer_encode(self, input, errors, final):
|
| 232 |
+
# Overwrite this method in subclasses: It must encode input
|
| 233 |
+
# and return an (output, length consumed) tuple
|
| 234 |
+
raise NotImplementedError
|
| 235 |
+
|
| 236 |
+
def encode(self, input, final=False):
|
| 237 |
+
# encode input (taking the buffer into account)
|
| 238 |
+
data = self.buffer + input
|
| 239 |
+
(result, consumed) = self._buffer_encode(data, self.errors, final)
|
| 240 |
+
# keep unencoded input until the next call
|
| 241 |
+
self.buffer = data[consumed:]
|
| 242 |
+
return result
|
| 243 |
+
|
| 244 |
+
def reset(self):
|
| 245 |
+
IncrementalEncoder.reset(self)
|
| 246 |
+
self.buffer = ""
|
| 247 |
+
|
| 248 |
+
def getstate(self):
|
| 249 |
+
return self.buffer or 0
|
| 250 |
+
|
| 251 |
+
def setstate(self, state):
|
| 252 |
+
self.buffer = state or ""
|
| 253 |
+
|
| 254 |
+
class IncrementalDecoder(object):
|
| 255 |
+
"""
|
| 256 |
+
An IncrementalDecoder decodes an input in multiple steps. The input can
|
| 257 |
+
be passed piece by piece to the decode() method. The IncrementalDecoder
|
| 258 |
+
remembers the state of the decoding process between calls to decode().
|
| 259 |
+
"""
|
| 260 |
+
def __init__(self, errors='strict'):
|
| 261 |
+
"""
|
| 262 |
+
Create an IncrementalDecoder instance.
|
| 263 |
+
|
| 264 |
+
The IncrementalDecoder may use different error handling schemes by
|
| 265 |
+
providing the errors keyword argument. See the module docstring
|
| 266 |
+
for a list of possible values.
|
| 267 |
+
"""
|
| 268 |
+
self.errors = errors
|
| 269 |
+
|
| 270 |
+
def decode(self, input, final=False):
|
| 271 |
+
"""
|
| 272 |
+
Decode input and returns the resulting object.
|
| 273 |
+
"""
|
| 274 |
+
raise NotImplementedError
|
| 275 |
+
|
| 276 |
+
def reset(self):
|
| 277 |
+
"""
|
| 278 |
+
Reset the decoder to the initial state.
|
| 279 |
+
"""
|
| 280 |
+
|
| 281 |
+
def getstate(self):
|
| 282 |
+
"""
|
| 283 |
+
Return the current state of the decoder.
|
| 284 |
+
|
| 285 |
+
This must be a (buffered_input, additional_state_info) tuple.
|
| 286 |
+
buffered_input must be a bytes object containing bytes that
|
| 287 |
+
were passed to decode() that have not yet been converted.
|
| 288 |
+
additional_state_info must be a non-negative integer
|
| 289 |
+
representing the state of the decoder WITHOUT yet having
|
| 290 |
+
processed the contents of buffered_input. In the initial state
|
| 291 |
+
and after reset(), getstate() must return (b"", 0).
|
| 292 |
+
"""
|
| 293 |
+
return (b"", 0)
|
| 294 |
+
|
| 295 |
+
def setstate(self, state):
|
| 296 |
+
"""
|
| 297 |
+
Set the current state of the decoder.
|
| 298 |
+
|
| 299 |
+
state must have been returned by getstate(). The effect of
|
| 300 |
+
setstate((b"", 0)) must be equivalent to reset().
|
| 301 |
+
"""
|
| 302 |
+
|
| 303 |
+
class BufferedIncrementalDecoder(IncrementalDecoder):
|
| 304 |
+
"""
|
| 305 |
+
This subclass of IncrementalDecoder can be used as the baseclass for an
|
| 306 |
+
incremental decoder if the decoder must be able to handle incomplete
|
| 307 |
+
byte sequences.
|
| 308 |
+
"""
|
| 309 |
+
def __init__(self, errors='strict'):
|
| 310 |
+
IncrementalDecoder.__init__(self, errors)
|
| 311 |
+
# undecoded input that is kept between calls to decode()
|
| 312 |
+
self.buffer = b""
|
| 313 |
+
|
| 314 |
+
def _buffer_decode(self, input, errors, final):
|
| 315 |
+
# Overwrite this method in subclasses: It must decode input
|
| 316 |
+
# and return an (output, length consumed) tuple
|
| 317 |
+
raise NotImplementedError
|
| 318 |
+
|
| 319 |
+
def decode(self, input, final=False):
|
| 320 |
+
# decode input (taking the buffer into account)
|
| 321 |
+
data = self.buffer + input
|
| 322 |
+
(result, consumed) = self._buffer_decode(data, self.errors, final)
|
| 323 |
+
# keep undecoded input until the next call
|
| 324 |
+
self.buffer = data[consumed:]
|
| 325 |
+
return result
|
| 326 |
+
|
| 327 |
+
def reset(self):
|
| 328 |
+
IncrementalDecoder.reset(self)
|
| 329 |
+
self.buffer = b""
|
| 330 |
+
|
| 331 |
+
def getstate(self):
|
| 332 |
+
# additional state info is always 0
|
| 333 |
+
return (self.buffer, 0)
|
| 334 |
+
|
| 335 |
+
def setstate(self, state):
|
| 336 |
+
# ignore additional state info
|
| 337 |
+
self.buffer = state[0]
|
| 338 |
+
|
| 339 |
+
#
|
| 340 |
+
# The StreamWriter and StreamReader class provide generic working
|
| 341 |
+
# interfaces which can be used to implement new encoding submodules
|
| 342 |
+
# very easily. See encodings/utf_8.py for an example on how this is
|
| 343 |
+
# done.
|
| 344 |
+
#
|
| 345 |
+
|
| 346 |
+
class StreamWriter(Codec):
|
| 347 |
+
|
| 348 |
+
def __init__(self, stream, errors='strict'):
|
| 349 |
+
|
| 350 |
+
""" Creates a StreamWriter instance.
|
| 351 |
+
|
| 352 |
+
stream must be a file-like object open for writing.
|
| 353 |
+
|
| 354 |
+
The StreamWriter may use different error handling
|
| 355 |
+
schemes by providing the errors keyword argument. These
|
| 356 |
+
parameters are predefined:
|
| 357 |
+
|
| 358 |
+
'strict' - raise a ValueError (or a subclass)
|
| 359 |
+
'ignore' - ignore the character and continue with the next
|
| 360 |
+
'replace'- replace with a suitable replacement character
|
| 361 |
+
'xmlcharrefreplace' - Replace with the appropriate XML
|
| 362 |
+
character reference.
|
| 363 |
+
'backslashreplace' - Replace with backslashed escape
|
| 364 |
+
sequences.
|
| 365 |
+
'namereplace' - Replace with \\N{...} escape sequences.
|
| 366 |
+
|
| 367 |
+
The set of allowed parameter values can be extended via
|
| 368 |
+
register_error.
|
| 369 |
+
"""
|
| 370 |
+
self.stream = stream
|
| 371 |
+
self.errors = errors
|
| 372 |
+
|
| 373 |
+
def write(self, object):
|
| 374 |
+
|
| 375 |
+
""" Writes the object's contents encoded to self.stream.
|
| 376 |
+
"""
|
| 377 |
+
data, consumed = self.encode(object, self.errors)
|
| 378 |
+
self.stream.write(data)
|
| 379 |
+
|
| 380 |
+
def writelines(self, list):
|
| 381 |
+
|
| 382 |
+
""" Writes the concatenated list of strings to the stream
|
| 383 |
+
using .write().
|
| 384 |
+
"""
|
| 385 |
+
self.write(''.join(list))
|
| 386 |
+
|
| 387 |
+
def reset(self):
|
| 388 |
+
|
| 389 |
+
""" Flushes and resets the codec buffers used for keeping state.
|
| 390 |
+
|
| 391 |
+
Calling this method should ensure that the data on the
|
| 392 |
+
output is put into a clean state, that allows appending
|
| 393 |
+
of new fresh data without having to rescan the whole
|
| 394 |
+
stream to recover state.
|
| 395 |
+
|
| 396 |
+
"""
|
| 397 |
+
pass
|
| 398 |
+
|
| 399 |
+
def seek(self, offset, whence=0):
|
| 400 |
+
self.stream.seek(offset, whence)
|
| 401 |
+
if whence == 0 and offset == 0:
|
| 402 |
+
self.reset()
|
| 403 |
+
|
| 404 |
+
def __getattr__(self, name,
|
| 405 |
+
getattr=getattr):
|
| 406 |
+
|
| 407 |
+
""" Inherit all other methods from the underlying stream.
|
| 408 |
+
"""
|
| 409 |
+
return getattr(self.stream, name)
|
| 410 |
+
|
| 411 |
+
def __enter__(self):
|
| 412 |
+
return self
|
| 413 |
+
|
| 414 |
+
def __exit__(self, type, value, tb):
|
| 415 |
+
self.stream.close()
|
| 416 |
+
|
| 417 |
+
###
|
| 418 |
+
|
| 419 |
+
class StreamReader(Codec):
|
| 420 |
+
|
| 421 |
+
charbuffertype = str
|
| 422 |
+
|
| 423 |
+
def __init__(self, stream, errors='strict'):
|
| 424 |
+
|
| 425 |
+
""" Creates a StreamReader instance.
|
| 426 |
+
|
| 427 |
+
stream must be a file-like object open for reading.
|
| 428 |
+
|
| 429 |
+
The StreamReader may use different error handling
|
| 430 |
+
schemes by providing the errors keyword argument. These
|
| 431 |
+
parameters are predefined:
|
| 432 |
+
|
| 433 |
+
'strict' - raise a ValueError (or a subclass)
|
| 434 |
+
'ignore' - ignore the character and continue with the next
|
| 435 |
+
'replace'- replace with a suitable replacement character
|
| 436 |
+
'backslashreplace' - Replace with backslashed escape sequences;
|
| 437 |
+
|
| 438 |
+
The set of allowed parameter values can be extended via
|
| 439 |
+
register_error.
|
| 440 |
+
"""
|
| 441 |
+
self.stream = stream
|
| 442 |
+
self.errors = errors
|
| 443 |
+
self.bytebuffer = b""
|
| 444 |
+
self._empty_charbuffer = self.charbuffertype()
|
| 445 |
+
self.charbuffer = self._empty_charbuffer
|
| 446 |
+
self.linebuffer = None
|
| 447 |
+
|
| 448 |
+
def decode(self, input, errors='strict'):
|
| 449 |
+
raise NotImplementedError
|
| 450 |
+
|
| 451 |
+
def read(self, size=-1, chars=-1, firstline=False):
|
| 452 |
+
|
| 453 |
+
""" Decodes data from the stream self.stream and returns the
|
| 454 |
+
resulting object.
|
| 455 |
+
|
| 456 |
+
chars indicates the number of decoded code points or bytes to
|
| 457 |
+
return. read() will never return more data than requested,
|
| 458 |
+
but it might return less, if there is not enough available.
|
| 459 |
+
|
| 460 |
+
size indicates the approximate maximum number of decoded
|
| 461 |
+
bytes or code points to read for decoding. The decoder
|
| 462 |
+
can modify this setting as appropriate. The default value
|
| 463 |
+
-1 indicates to read and decode as much as possible. size
|
| 464 |
+
is intended to prevent having to decode huge files in one
|
| 465 |
+
step.
|
| 466 |
+
|
| 467 |
+
If firstline is true, and a UnicodeDecodeError happens
|
| 468 |
+
after the first line terminator in the input only the first line
|
| 469 |
+
will be returned, the rest of the input will be kept until the
|
| 470 |
+
next call to read().
|
| 471 |
+
|
| 472 |
+
The method should use a greedy read strategy, meaning that
|
| 473 |
+
it should read as much data as is allowed within the
|
| 474 |
+
definition of the encoding and the given size, e.g. if
|
| 475 |
+
optional encoding endings or state markers are available
|
| 476 |
+
on the stream, these should be read too.
|
| 477 |
+
"""
|
| 478 |
+
# If we have lines cached, first merge them back into characters
|
| 479 |
+
if self.linebuffer:
|
| 480 |
+
self.charbuffer = self._empty_charbuffer.join(self.linebuffer)
|
| 481 |
+
self.linebuffer = None
|
| 482 |
+
|
| 483 |
+
if chars < 0:
|
| 484 |
+
# For compatibility with other read() methods that take a
|
| 485 |
+
# single argument
|
| 486 |
+
chars = size
|
| 487 |
+
|
| 488 |
+
# read until we get the required number of characters (if available)
|
| 489 |
+
while True:
|
| 490 |
+
# can the request be satisfied from the character buffer?
|
| 491 |
+
if chars >= 0:
|
| 492 |
+
if len(self.charbuffer) >= chars:
|
| 493 |
+
break
|
| 494 |
+
# we need more data
|
| 495 |
+
if size < 0:
|
| 496 |
+
newdata = self.stream.read()
|
| 497 |
+
else:
|
| 498 |
+
newdata = self.stream.read(size)
|
| 499 |
+
# decode bytes (those remaining from the last call included)
|
| 500 |
+
data = self.bytebuffer + newdata
|
| 501 |
+
if not data:
|
| 502 |
+
break
|
| 503 |
+
try:
|
| 504 |
+
newchars, decodedbytes = self.decode(data, self.errors)
|
| 505 |
+
except UnicodeDecodeError as exc:
|
| 506 |
+
if firstline:
|
| 507 |
+
newchars, decodedbytes = \
|
| 508 |
+
self.decode(data[:exc.start], self.errors)
|
| 509 |
+
lines = newchars.splitlines(keepends=True)
|
| 510 |
+
if len(lines)<=1:
|
| 511 |
+
raise
|
| 512 |
+
else:
|
| 513 |
+
raise
|
| 514 |
+
# keep undecoded bytes until the next call
|
| 515 |
+
self.bytebuffer = data[decodedbytes:]
|
| 516 |
+
# put new characters in the character buffer
|
| 517 |
+
self.charbuffer += newchars
|
| 518 |
+
# there was no data available
|
| 519 |
+
if not newdata:
|
| 520 |
+
break
|
| 521 |
+
if chars < 0:
|
| 522 |
+
# Return everything we've got
|
| 523 |
+
result = self.charbuffer
|
| 524 |
+
self.charbuffer = self._empty_charbuffer
|
| 525 |
+
else:
|
| 526 |
+
# Return the first chars characters
|
| 527 |
+
result = self.charbuffer[:chars]
|
| 528 |
+
self.charbuffer = self.charbuffer[chars:]
|
| 529 |
+
return result
|
| 530 |
+
|
| 531 |
+
def readline(self, size=None, keepends=True):
|
| 532 |
+
|
| 533 |
+
""" Read one line from the input stream and return the
|
| 534 |
+
decoded data.
|
| 535 |
+
|
| 536 |
+
size, if given, is passed as size argument to the
|
| 537 |
+
read() method.
|
| 538 |
+
|
| 539 |
+
"""
|
| 540 |
+
# If we have lines cached from an earlier read, return
|
| 541 |
+
# them unconditionally
|
| 542 |
+
if self.linebuffer:
|
| 543 |
+
line = self.linebuffer[0]
|
| 544 |
+
del self.linebuffer[0]
|
| 545 |
+
if len(self.linebuffer) == 1:
|
| 546 |
+
# revert to charbuffer mode; we might need more data
|
| 547 |
+
# next time
|
| 548 |
+
self.charbuffer = self.linebuffer[0]
|
| 549 |
+
self.linebuffer = None
|
| 550 |
+
if not keepends:
|
| 551 |
+
line = line.splitlines(keepends=False)[0]
|
| 552 |
+
return line
|
| 553 |
+
|
| 554 |
+
readsize = size or 72
|
| 555 |
+
line = self._empty_charbuffer
|
| 556 |
+
# If size is given, we call read() only once
|
| 557 |
+
while True:
|
| 558 |
+
data = self.read(readsize, firstline=True)
|
| 559 |
+
if data:
|
| 560 |
+
# If we're at a "\r" read one extra character (which might
|
| 561 |
+
# be a "\n") to get a proper line ending. If the stream is
|
| 562 |
+
# temporarily exhausted we return the wrong line ending.
|
| 563 |
+
if (isinstance(data, str) and data.endswith("\r")) or \
|
| 564 |
+
(isinstance(data, bytes) and data.endswith(b"\r")):
|
| 565 |
+
data += self.read(size=1, chars=1)
|
| 566 |
+
|
| 567 |
+
line += data
|
| 568 |
+
lines = line.splitlines(keepends=True)
|
| 569 |
+
if lines:
|
| 570 |
+
if len(lines) > 1:
|
| 571 |
+
# More than one line result; the first line is a full line
|
| 572 |
+
# to return
|
| 573 |
+
line = lines[0]
|
| 574 |
+
del lines[0]
|
| 575 |
+
if len(lines) > 1:
|
| 576 |
+
# cache the remaining lines
|
| 577 |
+
lines[-1] += self.charbuffer
|
| 578 |
+
self.linebuffer = lines
|
| 579 |
+
self.charbuffer = None
|
| 580 |
+
else:
|
| 581 |
+
# only one remaining line, put it back into charbuffer
|
| 582 |
+
self.charbuffer = lines[0] + self.charbuffer
|
| 583 |
+
if not keepends:
|
| 584 |
+
line = line.splitlines(keepends=False)[0]
|
| 585 |
+
break
|
| 586 |
+
line0withend = lines[0]
|
| 587 |
+
line0withoutend = lines[0].splitlines(keepends=False)[0]
|
| 588 |
+
if line0withend != line0withoutend: # We really have a line end
|
| 589 |
+
# Put the rest back together and keep it until the next call
|
| 590 |
+
self.charbuffer = self._empty_charbuffer.join(lines[1:]) + \
|
| 591 |
+
self.charbuffer
|
| 592 |
+
if keepends:
|
| 593 |
+
line = line0withend
|
| 594 |
+
else:
|
| 595 |
+
line = line0withoutend
|
| 596 |
+
break
|
| 597 |
+
# we didn't get anything or this was our only try
|
| 598 |
+
if not data or size is not None:
|
| 599 |
+
if line and not keepends:
|
| 600 |
+
line = line.splitlines(keepends=False)[0]
|
| 601 |
+
break
|
| 602 |
+
if readsize < 8000:
|
| 603 |
+
readsize *= 2
|
| 604 |
+
return line
|
| 605 |
+
|
| 606 |
+
def readlines(self, sizehint=None, keepends=True):
|
| 607 |
+
|
| 608 |
+
""" Read all lines available on the input stream
|
| 609 |
+
and return them as a list.
|
| 610 |
+
|
| 611 |
+
Line breaks are implemented using the codec's decoder
|
| 612 |
+
method and are included in the list entries.
|
| 613 |
+
|
| 614 |
+
sizehint, if given, is ignored since there is no efficient
|
| 615 |
+
way to finding the true end-of-line.
|
| 616 |
+
|
| 617 |
+
"""
|
| 618 |
+
data = self.read()
|
| 619 |
+
return data.splitlines(keepends)
|
| 620 |
+
|
| 621 |
+
def reset(self):
|
| 622 |
+
|
| 623 |
+
""" Resets the codec buffers used for keeping state.
|
| 624 |
+
|
| 625 |
+
Note that no stream repositioning should take place.
|
| 626 |
+
This method is primarily intended to be able to recover
|
| 627 |
+
from decoding errors.
|
| 628 |
+
|
| 629 |
+
"""
|
| 630 |
+
self.bytebuffer = b""
|
| 631 |
+
self.charbuffer = self._empty_charbuffer
|
| 632 |
+
self.linebuffer = None
|
| 633 |
+
|
| 634 |
+
def seek(self, offset, whence=0):
|
| 635 |
+
""" Set the input stream's current position.
|
| 636 |
+
|
| 637 |
+
Resets the codec buffers used for keeping state.
|
| 638 |
+
"""
|
| 639 |
+
self.stream.seek(offset, whence)
|
| 640 |
+
self.reset()
|
| 641 |
+
|
| 642 |
+
def __next__(self):
|
| 643 |
+
|
| 644 |
+
""" Return the next decoded line from the input stream."""
|
| 645 |
+
line = self.readline()
|
| 646 |
+
if line:
|
| 647 |
+
return line
|
| 648 |
+
raise StopIteration
|
| 649 |
+
|
| 650 |
+
def __iter__(self):
|
| 651 |
+
return self
|
| 652 |
+
|
| 653 |
+
def __getattr__(self, name,
|
| 654 |
+
getattr=getattr):
|
| 655 |
+
|
| 656 |
+
""" Inherit all other methods from the underlying stream.
|
| 657 |
+
"""
|
| 658 |
+
return getattr(self.stream, name)
|
| 659 |
+
|
| 660 |
+
def __enter__(self):
|
| 661 |
+
return self
|
| 662 |
+
|
| 663 |
+
def __exit__(self, type, value, tb):
|
| 664 |
+
self.stream.close()
|
| 665 |
+
|
| 666 |
+
###
|
| 667 |
+
|
| 668 |
+
class StreamReaderWriter:
|
| 669 |
+
|
| 670 |
+
""" StreamReaderWriter instances allow wrapping streams which
|
| 671 |
+
work in both read and write modes.
|
| 672 |
+
|
| 673 |
+
The design is such that one can use the factory functions
|
| 674 |
+
returned by the codec.lookup() function to construct the
|
| 675 |
+
instance.
|
| 676 |
+
|
| 677 |
+
"""
|
| 678 |
+
# Optional attributes set by the file wrappers below
|
| 679 |
+
encoding = 'unknown'
|
| 680 |
+
|
| 681 |
+
def __init__(self, stream, Reader, Writer, errors='strict'):
|
| 682 |
+
|
| 683 |
+
""" Creates a StreamReaderWriter instance.
|
| 684 |
+
|
| 685 |
+
stream must be a Stream-like object.
|
| 686 |
+
|
| 687 |
+
Reader, Writer must be factory functions or classes
|
| 688 |
+
providing the StreamReader, StreamWriter interface resp.
|
| 689 |
+
|
| 690 |
+
Error handling is done in the same way as defined for the
|
| 691 |
+
StreamWriter/Readers.
|
| 692 |
+
|
| 693 |
+
"""
|
| 694 |
+
self.stream = stream
|
| 695 |
+
self.reader = Reader(stream, errors)
|
| 696 |
+
self.writer = Writer(stream, errors)
|
| 697 |
+
self.errors = errors
|
| 698 |
+
|
| 699 |
+
def read(self, size=-1):
|
| 700 |
+
|
| 701 |
+
return self.reader.read(size)
|
| 702 |
+
|
| 703 |
+
def readline(self, size=None):
|
| 704 |
+
|
| 705 |
+
return self.reader.readline(size)
|
| 706 |
+
|
| 707 |
+
def readlines(self, sizehint=None):
|
| 708 |
+
|
| 709 |
+
return self.reader.readlines(sizehint)
|
| 710 |
+
|
| 711 |
+
def __next__(self):
|
| 712 |
+
|
| 713 |
+
""" Return the next decoded line from the input stream."""
|
| 714 |
+
return next(self.reader)
|
| 715 |
+
|
| 716 |
+
def __iter__(self):
|
| 717 |
+
return self
|
| 718 |
+
|
| 719 |
+
def write(self, data):
|
| 720 |
+
|
| 721 |
+
return self.writer.write(data)
|
| 722 |
+
|
| 723 |
+
def writelines(self, list):
|
| 724 |
+
|
| 725 |
+
return self.writer.writelines(list)
|
| 726 |
+
|
| 727 |
+
def reset(self):
|
| 728 |
+
|
| 729 |
+
self.reader.reset()
|
| 730 |
+
self.writer.reset()
|
| 731 |
+
|
| 732 |
+
def seek(self, offset, whence=0):
|
| 733 |
+
self.stream.seek(offset, whence)
|
| 734 |
+
self.reader.reset()
|
| 735 |
+
if whence == 0 and offset == 0:
|
| 736 |
+
self.writer.reset()
|
| 737 |
+
|
| 738 |
+
def __getattr__(self, name,
|
| 739 |
+
getattr=getattr):
|
| 740 |
+
|
| 741 |
+
""" Inherit all other methods from the underlying stream.
|
| 742 |
+
"""
|
| 743 |
+
return getattr(self.stream, name)
|
| 744 |
+
|
| 745 |
+
# these are needed to make "with StreamReaderWriter(...)" work properly
|
| 746 |
+
|
| 747 |
+
def __enter__(self):
|
| 748 |
+
return self
|
| 749 |
+
|
| 750 |
+
def __exit__(self, type, value, tb):
|
| 751 |
+
self.stream.close()
|
| 752 |
+
|
| 753 |
+
###
|
| 754 |
+
|
| 755 |
+
class StreamRecoder:
|
| 756 |
+
|
| 757 |
+
""" StreamRecoder instances translate data from one encoding to another.
|
| 758 |
+
|
| 759 |
+
They use the complete set of APIs returned by the
|
| 760 |
+
codecs.lookup() function to implement their task.
|
| 761 |
+
|
| 762 |
+
Data written to the StreamRecoder is first decoded into an
|
| 763 |
+
intermediate format (depending on the "decode" codec) and then
|
| 764 |
+
written to the underlying stream using an instance of the provided
|
| 765 |
+
Writer class.
|
| 766 |
+
|
| 767 |
+
In the other direction, data is read from the underlying stream using
|
| 768 |
+
a Reader instance and then encoded and returned to the caller.
|
| 769 |
+
|
| 770 |
+
"""
|
| 771 |
+
# Optional attributes set by the file wrappers below
|
| 772 |
+
data_encoding = 'unknown'
|
| 773 |
+
file_encoding = 'unknown'
|
| 774 |
+
|
| 775 |
+
def __init__(self, stream, encode, decode, Reader, Writer,
|
| 776 |
+
errors='strict'):
|
| 777 |
+
|
| 778 |
+
""" Creates a StreamRecoder instance which implements a two-way
|
| 779 |
+
conversion: encode and decode work on the frontend (the
|
| 780 |
+
data visible to .read() and .write()) while Reader and Writer
|
| 781 |
+
work on the backend (the data in stream).
|
| 782 |
+
|
| 783 |
+
You can use these objects to do transparent
|
| 784 |
+
transcodings from e.g. latin-1 to utf-8 and back.
|
| 785 |
+
|
| 786 |
+
stream must be a file-like object.
|
| 787 |
+
|
| 788 |
+
encode and decode must adhere to the Codec interface; Reader and
|
| 789 |
+
Writer must be factory functions or classes providing the
|
| 790 |
+
StreamReader and StreamWriter interfaces resp.
|
| 791 |
+
|
| 792 |
+
Error handling is done in the same way as defined for the
|
| 793 |
+
StreamWriter/Readers.
|
| 794 |
+
|
| 795 |
+
"""
|
| 796 |
+
self.stream = stream
|
| 797 |
+
self.encode = encode
|
| 798 |
+
self.decode = decode
|
| 799 |
+
self.reader = Reader(stream, errors)
|
| 800 |
+
self.writer = Writer(stream, errors)
|
| 801 |
+
self.errors = errors
|
| 802 |
+
|
| 803 |
+
def read(self, size=-1):
|
| 804 |
+
|
| 805 |
+
data = self.reader.read(size)
|
| 806 |
+
data, bytesencoded = self.encode(data, self.errors)
|
| 807 |
+
return data
|
| 808 |
+
|
| 809 |
+
def readline(self, size=None):
|
| 810 |
+
|
| 811 |
+
if size is None:
|
| 812 |
+
data = self.reader.readline()
|
| 813 |
+
else:
|
| 814 |
+
data = self.reader.readline(size)
|
| 815 |
+
data, bytesencoded = self.encode(data, self.errors)
|
| 816 |
+
return data
|
| 817 |
+
|
| 818 |
+
def readlines(self, sizehint=None):
|
| 819 |
+
|
| 820 |
+
data = self.reader.read()
|
| 821 |
+
data, bytesencoded = self.encode(data, self.errors)
|
| 822 |
+
return data.splitlines(keepends=True)
|
| 823 |
+
|
| 824 |
+
def __next__(self):
|
| 825 |
+
|
| 826 |
+
""" Return the next decoded line from the input stream."""
|
| 827 |
+
data = next(self.reader)
|
| 828 |
+
data, bytesencoded = self.encode(data, self.errors)
|
| 829 |
+
return data
|
| 830 |
+
|
| 831 |
+
def __iter__(self):
|
| 832 |
+
return self
|
| 833 |
+
|
| 834 |
+
def write(self, data):
|
| 835 |
+
|
| 836 |
+
data, bytesdecoded = self.decode(data, self.errors)
|
| 837 |
+
return self.writer.write(data)
|
| 838 |
+
|
| 839 |
+
def writelines(self, list):
|
| 840 |
+
|
| 841 |
+
data = b''.join(list)
|
| 842 |
+
data, bytesdecoded = self.decode(data, self.errors)
|
| 843 |
+
return self.writer.write(data)
|
| 844 |
+
|
| 845 |
+
def reset(self):
|
| 846 |
+
|
| 847 |
+
self.reader.reset()
|
| 848 |
+
self.writer.reset()
|
| 849 |
+
|
| 850 |
+
def seek(self, offset, whence=0):
|
| 851 |
+
# Seeks must be propagated to both the readers and writers
|
| 852 |
+
# as they might need to reset their internal buffers.
|
| 853 |
+
self.reader.seek(offset, whence)
|
| 854 |
+
self.writer.seek(offset, whence)
|
| 855 |
+
|
| 856 |
+
def __getattr__(self, name,
|
| 857 |
+
getattr=getattr):
|
| 858 |
+
|
| 859 |
+
""" Inherit all other methods from the underlying stream.
|
| 860 |
+
"""
|
| 861 |
+
return getattr(self.stream, name)
|
| 862 |
+
|
| 863 |
+
def __enter__(self):
|
| 864 |
+
return self
|
| 865 |
+
|
| 866 |
+
def __exit__(self, type, value, tb):
|
| 867 |
+
self.stream.close()
|
| 868 |
+
|
| 869 |
+
### Shortcuts
|
| 870 |
+
|
| 871 |
+
def open(filename, mode='r', encoding=None, errors='strict', buffering=-1):
|
| 872 |
+
|
| 873 |
+
""" Open an encoded file using the given mode and return
|
| 874 |
+
a wrapped version providing transparent encoding/decoding.
|
| 875 |
+
|
| 876 |
+
Note: The wrapped version will only accept the object format
|
| 877 |
+
defined by the codecs, i.e. Unicode objects for most builtin
|
| 878 |
+
codecs. Output is also codec dependent and will usually be
|
| 879 |
+
Unicode as well.
|
| 880 |
+
|
| 881 |
+
Underlying encoded files are always opened in binary mode.
|
| 882 |
+
The default file mode is 'r', meaning to open the file in read mode.
|
| 883 |
+
|
| 884 |
+
encoding specifies the encoding which is to be used for the
|
| 885 |
+
file.
|
| 886 |
+
|
| 887 |
+
errors may be given to define the error handling. It defaults
|
| 888 |
+
to 'strict' which causes ValueErrors to be raised in case an
|
| 889 |
+
encoding error occurs.
|
| 890 |
+
|
| 891 |
+
buffering has the same meaning as for the builtin open() API.
|
| 892 |
+
It defaults to -1 which means that the default buffer size will
|
| 893 |
+
be used.
|
| 894 |
+
|
| 895 |
+
The returned wrapped file object provides an extra attribute
|
| 896 |
+
.encoding which allows querying the used encoding. This
|
| 897 |
+
attribute is only available if an encoding was specified as
|
| 898 |
+
parameter.
|
| 899 |
+
|
| 900 |
+
"""
|
| 901 |
+
if encoding is not None and \
|
| 902 |
+
'b' not in mode:
|
| 903 |
+
# Force opening of the file in binary mode
|
| 904 |
+
mode = mode + 'b'
|
| 905 |
+
file = builtins.open(filename, mode, buffering)
|
| 906 |
+
if encoding is None:
|
| 907 |
+
return file
|
| 908 |
+
|
| 909 |
+
try:
|
| 910 |
+
info = lookup(encoding)
|
| 911 |
+
srw = StreamReaderWriter(file, info.streamreader, info.streamwriter, errors)
|
| 912 |
+
# Add attributes to simplify introspection
|
| 913 |
+
srw.encoding = encoding
|
| 914 |
+
return srw
|
| 915 |
+
except:
|
| 916 |
+
file.close()
|
| 917 |
+
raise
|
| 918 |
+
|
| 919 |
+
def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'):
|
| 920 |
+
|
| 921 |
+
""" Return a wrapped version of file which provides transparent
|
| 922 |
+
encoding translation.
|
| 923 |
+
|
| 924 |
+
Data written to the wrapped file is decoded according
|
| 925 |
+
to the given data_encoding and then encoded to the underlying
|
| 926 |
+
file using file_encoding. The intermediate data type
|
| 927 |
+
will usually be Unicode but depends on the specified codecs.
|
| 928 |
+
|
| 929 |
+
Bytes read from the file are decoded using file_encoding and then
|
| 930 |
+
passed back to the caller encoded using data_encoding.
|
| 931 |
+
|
| 932 |
+
If file_encoding is not given, it defaults to data_encoding.
|
| 933 |
+
|
| 934 |
+
errors may be given to define the error handling. It defaults
|
| 935 |
+
to 'strict' which causes ValueErrors to be raised in case an
|
| 936 |
+
encoding error occurs.
|
| 937 |
+
|
| 938 |
+
The returned wrapped file object provides two extra attributes
|
| 939 |
+
.data_encoding and .file_encoding which reflect the given
|
| 940 |
+
parameters of the same name. The attributes can be used for
|
| 941 |
+
introspection by Python programs.
|
| 942 |
+
|
| 943 |
+
"""
|
| 944 |
+
if file_encoding is None:
|
| 945 |
+
file_encoding = data_encoding
|
| 946 |
+
data_info = lookup(data_encoding)
|
| 947 |
+
file_info = lookup(file_encoding)
|
| 948 |
+
sr = StreamRecoder(file, data_info.encode, data_info.decode,
|
| 949 |
+
file_info.streamreader, file_info.streamwriter, errors)
|
| 950 |
+
# Add attributes to simplify introspection
|
| 951 |
+
sr.data_encoding = data_encoding
|
| 952 |
+
sr.file_encoding = file_encoding
|
| 953 |
+
return sr
|
| 954 |
+
|
| 955 |
+
### Helpers for codec lookup
|
| 956 |
+
|
| 957 |
+
def getencoder(encoding):
|
| 958 |
+
|
| 959 |
+
""" Lookup up the codec for the given encoding and return
|
| 960 |
+
its encoder function.
|
| 961 |
+
|
| 962 |
+
Raises a LookupError in case the encoding cannot be found.
|
| 963 |
+
|
| 964 |
+
"""
|
| 965 |
+
return lookup(encoding).encode
|
| 966 |
+
|
| 967 |
+
def getdecoder(encoding):
|
| 968 |
+
|
| 969 |
+
""" Lookup up the codec for the given encoding and return
|
| 970 |
+
its decoder function.
|
| 971 |
+
|
| 972 |
+
Raises a LookupError in case the encoding cannot be found.
|
| 973 |
+
|
| 974 |
+
"""
|
| 975 |
+
return lookup(encoding).decode
|
| 976 |
+
|
| 977 |
+
def getincrementalencoder(encoding):
|
| 978 |
+
|
| 979 |
+
""" Lookup up the codec for the given encoding and return
|
| 980 |
+
its IncrementalEncoder class or factory function.
|
| 981 |
+
|
| 982 |
+
Raises a LookupError in case the encoding cannot be found
|
| 983 |
+
or the codecs doesn't provide an incremental encoder.
|
| 984 |
+
|
| 985 |
+
"""
|
| 986 |
+
encoder = lookup(encoding).incrementalencoder
|
| 987 |
+
if encoder is None:
|
| 988 |
+
raise LookupError(encoding)
|
| 989 |
+
return encoder
|
| 990 |
+
|
| 991 |
+
def getincrementaldecoder(encoding):
|
| 992 |
+
|
| 993 |
+
""" Lookup up the codec for the given encoding and return
|
| 994 |
+
its IncrementalDecoder class or factory function.
|
| 995 |
+
|
| 996 |
+
Raises a LookupError in case the encoding cannot be found
|
| 997 |
+
or the codecs doesn't provide an incremental decoder.
|
| 998 |
+
|
| 999 |
+
"""
|
| 1000 |
+
decoder = lookup(encoding).incrementaldecoder
|
| 1001 |
+
if decoder is None:
|
| 1002 |
+
raise LookupError(encoding)
|
| 1003 |
+
return decoder
|
| 1004 |
+
|
| 1005 |
+
def getreader(encoding):
|
| 1006 |
+
|
| 1007 |
+
""" Lookup up the codec for the given encoding and return
|
| 1008 |
+
its StreamReader class or factory function.
|
| 1009 |
+
|
| 1010 |
+
Raises a LookupError in case the encoding cannot be found.
|
| 1011 |
+
|
| 1012 |
+
"""
|
| 1013 |
+
return lookup(encoding).streamreader
|
| 1014 |
+
|
| 1015 |
+
def getwriter(encoding):
|
| 1016 |
+
|
| 1017 |
+
""" Lookup up the codec for the given encoding and return
|
| 1018 |
+
its StreamWriter class or factory function.
|
| 1019 |
+
|
| 1020 |
+
Raises a LookupError in case the encoding cannot be found.
|
| 1021 |
+
|
| 1022 |
+
"""
|
| 1023 |
+
return lookup(encoding).streamwriter
|
| 1024 |
+
|
| 1025 |
+
def iterencode(iterator, encoding, errors='strict', **kwargs):
|
| 1026 |
+
"""
|
| 1027 |
+
Encoding iterator.
|
| 1028 |
+
|
| 1029 |
+
Encodes the input strings from the iterator using an IncrementalEncoder.
|
| 1030 |
+
|
| 1031 |
+
errors and kwargs are passed through to the IncrementalEncoder
|
| 1032 |
+
constructor.
|
| 1033 |
+
"""
|
| 1034 |
+
encoder = getincrementalencoder(encoding)(errors, **kwargs)
|
| 1035 |
+
for input in iterator:
|
| 1036 |
+
output = encoder.encode(input)
|
| 1037 |
+
if output:
|
| 1038 |
+
yield output
|
| 1039 |
+
output = encoder.encode("", True)
|
| 1040 |
+
if output:
|
| 1041 |
+
yield output
|
| 1042 |
+
|
| 1043 |
+
def iterdecode(iterator, encoding, errors='strict', **kwargs):
|
| 1044 |
+
"""
|
| 1045 |
+
Decoding iterator.
|
| 1046 |
+
|
| 1047 |
+
Decodes the input strings from the iterator using an IncrementalDecoder.
|
| 1048 |
+
|
| 1049 |
+
errors and kwargs are passed through to the IncrementalDecoder
|
| 1050 |
+
constructor.
|
| 1051 |
+
"""
|
| 1052 |
+
decoder = getincrementaldecoder(encoding)(errors, **kwargs)
|
| 1053 |
+
for input in iterator:
|
| 1054 |
+
output = decoder.decode(input)
|
| 1055 |
+
if output:
|
| 1056 |
+
yield output
|
| 1057 |
+
output = decoder.decode(b"", True)
|
| 1058 |
+
if output:
|
| 1059 |
+
yield output
|
| 1060 |
+
|
| 1061 |
+
### Helpers for charmap-based codecs
|
| 1062 |
+
|
| 1063 |
+
def make_identity_dict(rng):
|
| 1064 |
+
|
| 1065 |
+
""" make_identity_dict(rng) -> dict
|
| 1066 |
+
|
| 1067 |
+
Return a dictionary where elements of the rng sequence are
|
| 1068 |
+
mapped to themselves.
|
| 1069 |
+
|
| 1070 |
+
"""
|
| 1071 |
+
return {i:i for i in rng}
|
| 1072 |
+
|
| 1073 |
+
def make_encoding_map(decoding_map):
|
| 1074 |
+
|
| 1075 |
+
""" Creates an encoding map from a decoding map.
|
| 1076 |
+
|
| 1077 |
+
If a target mapping in the decoding map occurs multiple
|
| 1078 |
+
times, then that target is mapped to None (undefined mapping),
|
| 1079 |
+
causing an exception when encountered by the charmap codec
|
| 1080 |
+
during translation.
|
| 1081 |
+
|
| 1082 |
+
One example where this happens is cp875.py which decodes
|
| 1083 |
+
multiple character to \\u001a.
|
| 1084 |
+
|
| 1085 |
+
"""
|
| 1086 |
+
m = {}
|
| 1087 |
+
for k,v in decoding_map.items():
|
| 1088 |
+
if not v in m:
|
| 1089 |
+
m[v] = k
|
| 1090 |
+
else:
|
| 1091 |
+
m[v] = None
|
| 1092 |
+
return m
|
| 1093 |
+
|
| 1094 |
+
### error handlers
|
| 1095 |
+
|
| 1096 |
+
try:
|
| 1097 |
+
strict_errors = lookup_error("strict")
|
| 1098 |
+
ignore_errors = lookup_error("ignore")
|
| 1099 |
+
replace_errors = lookup_error("replace")
|
| 1100 |
+
xmlcharrefreplace_errors = lookup_error("xmlcharrefreplace")
|
| 1101 |
+
backslashreplace_errors = lookup_error("backslashreplace")
|
| 1102 |
+
namereplace_errors = lookup_error("namereplace")
|
| 1103 |
+
except LookupError:
|
| 1104 |
+
# In --disable-unicode builds, these error handler are missing
|
| 1105 |
+
strict_errors = None
|
| 1106 |
+
ignore_errors = None
|
| 1107 |
+
replace_errors = None
|
| 1108 |
+
xmlcharrefreplace_errors = None
|
| 1109 |
+
backslashreplace_errors = None
|
| 1110 |
+
namereplace_errors = None
|
| 1111 |
+
|
| 1112 |
+
# Tell modulefinder that using codecs probably needs the encodings
|
| 1113 |
+
# package
|
| 1114 |
+
_false = 0
|
| 1115 |
+
if _false:
|
| 1116 |
+
import encodings
|
| 1117 |
+
|
| 1118 |
+
### Tests
|
| 1119 |
+
|
| 1120 |
+
if __name__ == '__main__':
|
| 1121 |
+
|
| 1122 |
+
# Make stdout translate Latin-1 output into UTF-8 output
|
| 1123 |
+
sys.stdout = EncodedFile(sys.stdout, 'latin-1', 'utf-8')
|
| 1124 |
+
|
| 1125 |
+
# Have stdin translate Latin-1 input into UTF-8 input
|
| 1126 |
+
sys.stdin = EncodedFile(sys.stdin, 'utf-8', 'latin-1')
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/codeop.py
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
r"""Utilities to compile possibly incomplete Python source code.
|
| 2 |
+
|
| 3 |
+
This module provides two interfaces, broadly similar to the builtin
|
| 4 |
+
function compile(), which take program text, a filename and a 'mode'
|
| 5 |
+
and:
|
| 6 |
+
|
| 7 |
+
- Return code object if the command is complete and valid
|
| 8 |
+
- Return None if the command is incomplete
|
| 9 |
+
- Raise SyntaxError, ValueError or OverflowError if the command is a
|
| 10 |
+
syntax error (OverflowError and ValueError can be produced by
|
| 11 |
+
malformed literals).
|
| 12 |
+
|
| 13 |
+
Approach:
|
| 14 |
+
|
| 15 |
+
First, check if the source consists entirely of blank lines and
|
| 16 |
+
comments; if so, replace it with 'pass', because the built-in
|
| 17 |
+
parser doesn't always do the right thing for these.
|
| 18 |
+
|
| 19 |
+
Compile three times: as is, with \n, and with \n\n appended. If it
|
| 20 |
+
compiles as is, it's complete. If it compiles with one \n appended,
|
| 21 |
+
we expect more. If it doesn't compile either way, we compare the
|
| 22 |
+
error we get when compiling with \n or \n\n appended. If the errors
|
| 23 |
+
are the same, the code is broken. But if the errors are different, we
|
| 24 |
+
expect more. Not intuitive; not even guaranteed to hold in future
|
| 25 |
+
releases; but this matches the compiler's behavior from Python 1.4
|
| 26 |
+
through 2.2, at least.
|
| 27 |
+
|
| 28 |
+
Caveat:
|
| 29 |
+
|
| 30 |
+
It is possible (but not likely) that the parser stops parsing with a
|
| 31 |
+
successful outcome before reaching the end of the source; in this
|
| 32 |
+
case, trailing symbols may be ignored instead of causing an error.
|
| 33 |
+
For example, a backslash followed by two newlines may be followed by
|
| 34 |
+
arbitrary garbage. This will be fixed once the API for the parser is
|
| 35 |
+
better.
|
| 36 |
+
|
| 37 |
+
The two interfaces are:
|
| 38 |
+
|
| 39 |
+
compile_command(source, filename, symbol):
|
| 40 |
+
|
| 41 |
+
Compiles a single command in the manner described above.
|
| 42 |
+
|
| 43 |
+
CommandCompiler():
|
| 44 |
+
|
| 45 |
+
Instances of this class have __call__ methods identical in
|
| 46 |
+
signature to compile_command; the difference is that if the
|
| 47 |
+
instance compiles program text containing a __future__ statement,
|
| 48 |
+
the instance 'remembers' and compiles all subsequent program texts
|
| 49 |
+
with the statement in force.
|
| 50 |
+
|
| 51 |
+
The module also provides another class:
|
| 52 |
+
|
| 53 |
+
Compile():
|
| 54 |
+
|
| 55 |
+
Instances of this class act like the built-in function compile,
|
| 56 |
+
but with 'memory' in the sense described above.
|
| 57 |
+
"""
|
| 58 |
+
|
| 59 |
+
import __future__
|
| 60 |
+
import warnings
|
| 61 |
+
|
| 62 |
+
_features = [getattr(__future__, fname)
|
| 63 |
+
for fname in __future__.all_feature_names]
|
| 64 |
+
|
| 65 |
+
__all__ = ["compile_command", "Compile", "CommandCompiler"]
|
| 66 |
+
|
| 67 |
+
PyCF_DONT_IMPLY_DEDENT = 0x200 # Matches pythonrun.h
|
| 68 |
+
|
| 69 |
+
def _maybe_compile(compiler, source, filename, symbol):
|
| 70 |
+
# Check for source consisting of only blank lines and comments
|
| 71 |
+
for line in source.split("\n"):
|
| 72 |
+
line = line.strip()
|
| 73 |
+
if line and line[0] != '#':
|
| 74 |
+
break # Leave it alone
|
| 75 |
+
else:
|
| 76 |
+
if symbol != "eval":
|
| 77 |
+
source = "pass" # Replace it with a 'pass' statement
|
| 78 |
+
|
| 79 |
+
err = err1 = err2 = None
|
| 80 |
+
code = code1 = code2 = None
|
| 81 |
+
|
| 82 |
+
try:
|
| 83 |
+
code = compiler(source, filename, symbol)
|
| 84 |
+
except SyntaxError as err:
|
| 85 |
+
pass
|
| 86 |
+
|
| 87 |
+
# Catch syntax warnings after the first compile
|
| 88 |
+
# to emit warnings (SyntaxWarning, DeprecationWarning) at most once.
|
| 89 |
+
with warnings.catch_warnings():
|
| 90 |
+
warnings.simplefilter("error")
|
| 91 |
+
|
| 92 |
+
try:
|
| 93 |
+
code1 = compiler(source + "\n", filename, symbol)
|
| 94 |
+
except SyntaxError as e:
|
| 95 |
+
err1 = e
|
| 96 |
+
|
| 97 |
+
try:
|
| 98 |
+
code2 = compiler(source + "\n\n", filename, symbol)
|
| 99 |
+
except SyntaxError as e:
|
| 100 |
+
err2 = e
|
| 101 |
+
|
| 102 |
+
try:
|
| 103 |
+
if code:
|
| 104 |
+
return code
|
| 105 |
+
if not code1 and repr(err1) == repr(err2):
|
| 106 |
+
raise err1
|
| 107 |
+
finally:
|
| 108 |
+
err1 = err2 = None
|
| 109 |
+
|
| 110 |
+
def _compile(source, filename, symbol):
|
| 111 |
+
return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT)
|
| 112 |
+
|
| 113 |
+
def compile_command(source, filename="<input>", symbol="single"):
|
| 114 |
+
r"""Compile a command and determine whether it is incomplete.
|
| 115 |
+
|
| 116 |
+
Arguments:
|
| 117 |
+
|
| 118 |
+
source -- the source string; may contain \n characters
|
| 119 |
+
filename -- optional filename from which source was read; default
|
| 120 |
+
"<input>"
|
| 121 |
+
symbol -- optional grammar start symbol; "single" (default), "exec"
|
| 122 |
+
or "eval"
|
| 123 |
+
|
| 124 |
+
Return value / exceptions raised:
|
| 125 |
+
|
| 126 |
+
- Return a code object if the command is complete and valid
|
| 127 |
+
- Return None if the command is incomplete
|
| 128 |
+
- Raise SyntaxError, ValueError or OverflowError if the command is a
|
| 129 |
+
syntax error (OverflowError and ValueError can be produced by
|
| 130 |
+
malformed literals).
|
| 131 |
+
"""
|
| 132 |
+
return _maybe_compile(_compile, source, filename, symbol)
|
| 133 |
+
|
| 134 |
+
class Compile:
|
| 135 |
+
"""Instances of this class behave much like the built-in compile
|
| 136 |
+
function, but if one is used to compile text containing a future
|
| 137 |
+
statement, it "remembers" and compiles all subsequent program texts
|
| 138 |
+
with the statement in force."""
|
| 139 |
+
def __init__(self):
|
| 140 |
+
self.flags = PyCF_DONT_IMPLY_DEDENT
|
| 141 |
+
|
| 142 |
+
def __call__(self, source, filename, symbol):
|
| 143 |
+
codeob = compile(source, filename, symbol, self.flags, 1)
|
| 144 |
+
for feature in _features:
|
| 145 |
+
if codeob.co_flags & feature.compiler_flag:
|
| 146 |
+
self.flags |= feature.compiler_flag
|
| 147 |
+
return codeob
|
| 148 |
+
|
| 149 |
+
class CommandCompiler:
|
| 150 |
+
"""Instances of this class have __call__ methods identical in
|
| 151 |
+
signature to compile_command; the difference is that if the
|
| 152 |
+
instance compiles program text containing a __future__ statement,
|
| 153 |
+
the instance 'remembers' and compiles all subsequent program texts
|
| 154 |
+
with the statement in force."""
|
| 155 |
+
|
| 156 |
+
def __init__(self,):
|
| 157 |
+
self.compiler = Compile()
|
| 158 |
+
|
| 159 |
+
def __call__(self, source, filename="<input>", symbol="single"):
|
| 160 |
+
r"""Compile a command and determine whether it is incomplete.
|
| 161 |
+
|
| 162 |
+
Arguments:
|
| 163 |
+
|
| 164 |
+
source -- the source string; may contain \n characters
|
| 165 |
+
filename -- optional filename from which source was read;
|
| 166 |
+
default "<input>"
|
| 167 |
+
symbol -- optional grammar start symbol; "single" (default) or
|
| 168 |
+
"eval"
|
| 169 |
+
|
| 170 |
+
Return value / exceptions raised:
|
| 171 |
+
|
| 172 |
+
- Return a code object if the command is complete and valid
|
| 173 |
+
- Return None if the command is incomplete
|
| 174 |
+
- Raise SyntaxError, ValueError or OverflowError if the command is a
|
| 175 |
+
syntax error (OverflowError and ValueError can be produced by
|
| 176 |
+
malformed literals).
|
| 177 |
+
"""
|
| 178 |
+
return _maybe_compile(self.compiler, source, filename, symbol)
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/crypt.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Wrapper to the POSIX crypt library call and associated functionality."""
|
| 2 |
+
|
| 3 |
+
import sys as _sys
|
| 4 |
+
|
| 5 |
+
try:
|
| 6 |
+
import _crypt
|
| 7 |
+
except ModuleNotFoundError:
|
| 8 |
+
if _sys.platform == 'win32':
|
| 9 |
+
raise ImportError("The crypt module is not supported on Windows")
|
| 10 |
+
else:
|
| 11 |
+
raise ImportError("The required _crypt module was not built as part of CPython")
|
| 12 |
+
|
| 13 |
+
import string as _string
|
| 14 |
+
from random import SystemRandom as _SystemRandom
|
| 15 |
+
from collections import namedtuple as _namedtuple
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
_saltchars = _string.ascii_letters + _string.digits + './'
|
| 19 |
+
_sr = _SystemRandom()
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
class _Method(_namedtuple('_Method', 'name ident salt_chars total_size')):
|
| 23 |
+
|
| 24 |
+
"""Class representing a salt method per the Modular Crypt Format or the
|
| 25 |
+
legacy 2-character crypt method."""
|
| 26 |
+
|
| 27 |
+
def __repr__(self):
|
| 28 |
+
return '<crypt.METHOD_{}>'.format(self.name)
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def mksalt(method=None, *, rounds=None):
|
| 32 |
+
"""Generate a salt for the specified method.
|
| 33 |
+
|
| 34 |
+
If not specified, the strongest available method will be used.
|
| 35 |
+
|
| 36 |
+
"""
|
| 37 |
+
if method is None:
|
| 38 |
+
method = methods[0]
|
| 39 |
+
if rounds is not None and not isinstance(rounds, int):
|
| 40 |
+
raise TypeError(f'{rounds.__class__.__name__} object cannot be '
|
| 41 |
+
f'interpreted as an integer')
|
| 42 |
+
if not method.ident: # traditional
|
| 43 |
+
s = ''
|
| 44 |
+
else: # modular
|
| 45 |
+
s = f'${method.ident}$'
|
| 46 |
+
|
| 47 |
+
if method.ident and method.ident[0] == '2': # Blowfish variants
|
| 48 |
+
if rounds is None:
|
| 49 |
+
log_rounds = 12
|
| 50 |
+
else:
|
| 51 |
+
log_rounds = int.bit_length(rounds-1)
|
| 52 |
+
if rounds != 1 << log_rounds:
|
| 53 |
+
raise ValueError('rounds must be a power of 2')
|
| 54 |
+
if not 4 <= log_rounds <= 31:
|
| 55 |
+
raise ValueError('rounds out of the range 2**4 to 2**31')
|
| 56 |
+
s += f'{log_rounds:02d}$'
|
| 57 |
+
elif method.ident in ('5', '6'): # SHA-2
|
| 58 |
+
if rounds is not None:
|
| 59 |
+
if not 1000 <= rounds <= 999_999_999:
|
| 60 |
+
raise ValueError('rounds out of the range 1000 to 999_999_999')
|
| 61 |
+
s += f'rounds={rounds}$'
|
| 62 |
+
elif rounds is not None:
|
| 63 |
+
raise ValueError(f"{method} doesn't support the rounds argument")
|
| 64 |
+
|
| 65 |
+
s += ''.join(_sr.choice(_saltchars) for char in range(method.salt_chars))
|
| 66 |
+
return s
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def crypt(word, salt=None):
|
| 70 |
+
"""Return a string representing the one-way hash of a password, with a salt
|
| 71 |
+
prepended.
|
| 72 |
+
|
| 73 |
+
If ``salt`` is not specified or is ``None``, the strongest
|
| 74 |
+
available method will be selected and a salt generated. Otherwise,
|
| 75 |
+
``salt`` may be one of the ``crypt.METHOD_*`` values, or a string as
|
| 76 |
+
returned by ``crypt.mksalt()``.
|
| 77 |
+
|
| 78 |
+
"""
|
| 79 |
+
if salt is None or isinstance(salt, _Method):
|
| 80 |
+
salt = mksalt(salt)
|
| 81 |
+
return _crypt.crypt(word, salt)
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
# available salting/crypto methods
|
| 85 |
+
methods = []
|
| 86 |
+
|
| 87 |
+
def _add_method(name, *args, rounds=None):
|
| 88 |
+
method = _Method(name, *args)
|
| 89 |
+
globals()['METHOD_' + name] = method
|
| 90 |
+
salt = mksalt(method, rounds=rounds)
|
| 91 |
+
result = crypt('', salt)
|
| 92 |
+
if result and len(result) == method.total_size:
|
| 93 |
+
methods.append(method)
|
| 94 |
+
return True
|
| 95 |
+
return False
|
| 96 |
+
|
| 97 |
+
_add_method('SHA512', '6', 16, 106)
|
| 98 |
+
_add_method('SHA256', '5', 16, 63)
|
| 99 |
+
|
| 100 |
+
# Choose the strongest supported version of Blowfish hashing.
|
| 101 |
+
# Early versions have flaws. Version 'a' fixes flaws of
|
| 102 |
+
# the initial implementation, 'b' fixes flaws of 'a'.
|
| 103 |
+
# 'y' is the same as 'b', for compatibility
|
| 104 |
+
# with openwall crypt_blowfish.
|
| 105 |
+
for _v in 'b', 'y', 'a', '':
|
| 106 |
+
if _add_method('BLOWFISH', '2' + _v, 22, 59 + len(_v), rounds=1<<4):
|
| 107 |
+
break
|
| 108 |
+
|
| 109 |
+
_add_method('MD5', '1', 8, 34)
|
| 110 |
+
_add_method('CRYPT', None, 2, 13)
|
| 111 |
+
|
| 112 |
+
del _v, _add_method
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/decimal.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
try:
|
| 3 |
+
from _decimal import *
|
| 4 |
+
from _decimal import __doc__
|
| 5 |
+
from _decimal import __version__
|
| 6 |
+
from _decimal import __libmpdec_version__
|
| 7 |
+
except ImportError:
|
| 8 |
+
from _pydecimal import *
|
| 9 |
+
from _pydecimal import __doc__
|
| 10 |
+
from _pydecimal import __version__
|
| 11 |
+
from _pydecimal import __libmpdec_version__
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/dis.py
ADDED
|
@@ -0,0 +1,553 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Disassembler of Python byte code into mnemonics."""
|
| 2 |
+
|
| 3 |
+
import sys
|
| 4 |
+
import types
|
| 5 |
+
import collections
|
| 6 |
+
import io
|
| 7 |
+
|
| 8 |
+
from opcode import *
|
| 9 |
+
from opcode import __all__ as _opcodes_all
|
| 10 |
+
|
| 11 |
+
__all__ = ["code_info", "dis", "disassemble", "distb", "disco",
|
| 12 |
+
"findlinestarts", "findlabels", "show_code",
|
| 13 |
+
"get_instructions", "Instruction", "Bytecode"] + _opcodes_all
|
| 14 |
+
del _opcodes_all
|
| 15 |
+
|
| 16 |
+
_have_code = (types.MethodType, types.FunctionType, types.CodeType,
|
| 17 |
+
classmethod, staticmethod, type)
|
| 18 |
+
|
| 19 |
+
FORMAT_VALUE = opmap['FORMAT_VALUE']
|
| 20 |
+
FORMAT_VALUE_CONVERTERS = (
|
| 21 |
+
(None, ''),
|
| 22 |
+
(str, 'str'),
|
| 23 |
+
(repr, 'repr'),
|
| 24 |
+
(ascii, 'ascii'),
|
| 25 |
+
)
|
| 26 |
+
MAKE_FUNCTION = opmap['MAKE_FUNCTION']
|
| 27 |
+
MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure')
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def _try_compile(source, name):
|
| 31 |
+
"""Attempts to compile the given source, first as an expression and
|
| 32 |
+
then as a statement if the first approach fails.
|
| 33 |
+
|
| 34 |
+
Utility function to accept strings in functions that otherwise
|
| 35 |
+
expect code objects
|
| 36 |
+
"""
|
| 37 |
+
try:
|
| 38 |
+
c = compile(source, name, 'eval')
|
| 39 |
+
except SyntaxError:
|
| 40 |
+
c = compile(source, name, 'exec')
|
| 41 |
+
return c
|
| 42 |
+
|
| 43 |
+
def dis(x=None, *, file=None, depth=None):
|
| 44 |
+
"""Disassemble classes, methods, functions, and other compiled objects.
|
| 45 |
+
|
| 46 |
+
With no argument, disassemble the last traceback.
|
| 47 |
+
|
| 48 |
+
Compiled objects currently include generator objects, async generator
|
| 49 |
+
objects, and coroutine objects, all of which store their code object
|
| 50 |
+
in a special attribute.
|
| 51 |
+
"""
|
| 52 |
+
if x is None:
|
| 53 |
+
distb(file=file)
|
| 54 |
+
return
|
| 55 |
+
# Extract functions from methods.
|
| 56 |
+
if hasattr(x, '__func__'):
|
| 57 |
+
x = x.__func__
|
| 58 |
+
# Extract compiled code objects from...
|
| 59 |
+
if hasattr(x, '__code__'): # ...a function, or
|
| 60 |
+
x = x.__code__
|
| 61 |
+
elif hasattr(x, 'gi_code'): #...a generator object, or
|
| 62 |
+
x = x.gi_code
|
| 63 |
+
elif hasattr(x, 'ag_code'): #...an asynchronous generator object, or
|
| 64 |
+
x = x.ag_code
|
| 65 |
+
elif hasattr(x, 'cr_code'): #...a coroutine.
|
| 66 |
+
x = x.cr_code
|
| 67 |
+
# Perform the disassembly.
|
| 68 |
+
if hasattr(x, '__dict__'): # Class or module
|
| 69 |
+
items = sorted(x.__dict__.items())
|
| 70 |
+
for name, x1 in items:
|
| 71 |
+
if isinstance(x1, _have_code):
|
| 72 |
+
print("Disassembly of %s:" % name, file=file)
|
| 73 |
+
try:
|
| 74 |
+
dis(x1, file=file, depth=depth)
|
| 75 |
+
except TypeError as msg:
|
| 76 |
+
print("Sorry:", msg, file=file)
|
| 77 |
+
print(file=file)
|
| 78 |
+
elif hasattr(x, 'co_code'): # Code object
|
| 79 |
+
_disassemble_recursive(x, file=file, depth=depth)
|
| 80 |
+
elif isinstance(x, (bytes, bytearray)): # Raw bytecode
|
| 81 |
+
_disassemble_bytes(x, file=file)
|
| 82 |
+
elif isinstance(x, str): # Source code
|
| 83 |
+
_disassemble_str(x, file=file, depth=depth)
|
| 84 |
+
else:
|
| 85 |
+
raise TypeError("don't know how to disassemble %s objects" %
|
| 86 |
+
type(x).__name__)
|
| 87 |
+
|
| 88 |
+
def distb(tb=None, *, file=None):
|
| 89 |
+
"""Disassemble a traceback (default: last traceback)."""
|
| 90 |
+
if tb is None:
|
| 91 |
+
try:
|
| 92 |
+
tb = sys.last_traceback
|
| 93 |
+
except AttributeError:
|
| 94 |
+
raise RuntimeError("no last traceback to disassemble") from None
|
| 95 |
+
while tb.tb_next: tb = tb.tb_next
|
| 96 |
+
disassemble(tb.tb_frame.f_code, tb.tb_lasti, file=file)
|
| 97 |
+
|
| 98 |
+
# The inspect module interrogates this dictionary to build its
|
| 99 |
+
# list of CO_* constants. It is also used by pretty_flags to
|
| 100 |
+
# turn the co_flags field into a human readable list.
|
| 101 |
+
COMPILER_FLAG_NAMES = {
|
| 102 |
+
1: "OPTIMIZED",
|
| 103 |
+
2: "NEWLOCALS",
|
| 104 |
+
4: "VARARGS",
|
| 105 |
+
8: "VARKEYWORDS",
|
| 106 |
+
16: "NESTED",
|
| 107 |
+
32: "GENERATOR",
|
| 108 |
+
64: "NOFREE",
|
| 109 |
+
128: "COROUTINE",
|
| 110 |
+
256: "ITERABLE_COROUTINE",
|
| 111 |
+
512: "ASYNC_GENERATOR",
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
def pretty_flags(flags):
|
| 115 |
+
"""Return pretty representation of code flags."""
|
| 116 |
+
names = []
|
| 117 |
+
for i in range(32):
|
| 118 |
+
flag = 1<<i
|
| 119 |
+
if flags & flag:
|
| 120 |
+
names.append(COMPILER_FLAG_NAMES.get(flag, hex(flag)))
|
| 121 |
+
flags ^= flag
|
| 122 |
+
if not flags:
|
| 123 |
+
break
|
| 124 |
+
else:
|
| 125 |
+
names.append(hex(flags))
|
| 126 |
+
return ", ".join(names)
|
| 127 |
+
|
| 128 |
+
def _get_code_object(x):
|
| 129 |
+
"""Helper to handle methods, compiled or raw code objects, and strings."""
|
| 130 |
+
# Extract functions from methods.
|
| 131 |
+
if hasattr(x, '__func__'):
|
| 132 |
+
x = x.__func__
|
| 133 |
+
# Extract compiled code objects from...
|
| 134 |
+
if hasattr(x, '__code__'): # ...a function, or
|
| 135 |
+
x = x.__code__
|
| 136 |
+
elif hasattr(x, 'gi_code'): #...a generator object, or
|
| 137 |
+
x = x.gi_code
|
| 138 |
+
elif hasattr(x, 'ag_code'): #...an asynchronous generator object, or
|
| 139 |
+
x = x.ag_code
|
| 140 |
+
elif hasattr(x, 'cr_code'): #...a coroutine.
|
| 141 |
+
x = x.cr_code
|
| 142 |
+
# Handle source code.
|
| 143 |
+
if isinstance(x, str):
|
| 144 |
+
x = _try_compile(x, "<disassembly>")
|
| 145 |
+
# By now, if we don't have a code object, we can't disassemble x.
|
| 146 |
+
if hasattr(x, 'co_code'):
|
| 147 |
+
return x
|
| 148 |
+
raise TypeError("don't know how to disassemble %s objects" %
|
| 149 |
+
type(x).__name__)
|
| 150 |
+
|
| 151 |
+
def code_info(x):
|
| 152 |
+
"""Formatted details of methods, functions, or code."""
|
| 153 |
+
return _format_code_info(_get_code_object(x))
|
| 154 |
+
|
| 155 |
+
def _format_code_info(co):
|
| 156 |
+
lines = []
|
| 157 |
+
lines.append("Name: %s" % co.co_name)
|
| 158 |
+
lines.append("Filename: %s" % co.co_filename)
|
| 159 |
+
lines.append("Argument count: %s" % co.co_argcount)
|
| 160 |
+
lines.append("Positional-only arguments: %s" % co.co_posonlyargcount)
|
| 161 |
+
lines.append("Kw-only arguments: %s" % co.co_kwonlyargcount)
|
| 162 |
+
lines.append("Number of locals: %s" % co.co_nlocals)
|
| 163 |
+
lines.append("Stack size: %s" % co.co_stacksize)
|
| 164 |
+
lines.append("Flags: %s" % pretty_flags(co.co_flags))
|
| 165 |
+
if co.co_consts:
|
| 166 |
+
lines.append("Constants:")
|
| 167 |
+
for i_c in enumerate(co.co_consts):
|
| 168 |
+
lines.append("%4d: %r" % i_c)
|
| 169 |
+
if co.co_names:
|
| 170 |
+
lines.append("Names:")
|
| 171 |
+
for i_n in enumerate(co.co_names):
|
| 172 |
+
lines.append("%4d: %s" % i_n)
|
| 173 |
+
if co.co_varnames:
|
| 174 |
+
lines.append("Variable names:")
|
| 175 |
+
for i_n in enumerate(co.co_varnames):
|
| 176 |
+
lines.append("%4d: %s" % i_n)
|
| 177 |
+
if co.co_freevars:
|
| 178 |
+
lines.append("Free variables:")
|
| 179 |
+
for i_n in enumerate(co.co_freevars):
|
| 180 |
+
lines.append("%4d: %s" % i_n)
|
| 181 |
+
if co.co_cellvars:
|
| 182 |
+
lines.append("Cell variables:")
|
| 183 |
+
for i_n in enumerate(co.co_cellvars):
|
| 184 |
+
lines.append("%4d: %s" % i_n)
|
| 185 |
+
return "\n".join(lines)
|
| 186 |
+
|
| 187 |
+
def show_code(co, *, file=None):
|
| 188 |
+
"""Print details of methods, functions, or code to *file*.
|
| 189 |
+
|
| 190 |
+
If *file* is not provided, the output is printed on stdout.
|
| 191 |
+
"""
|
| 192 |
+
print(code_info(co), file=file)
|
| 193 |
+
|
| 194 |
+
_Instruction = collections.namedtuple("_Instruction",
|
| 195 |
+
"opname opcode arg argval argrepr offset starts_line is_jump_target")
|
| 196 |
+
|
| 197 |
+
_Instruction.opname.__doc__ = "Human readable name for operation"
|
| 198 |
+
_Instruction.opcode.__doc__ = "Numeric code for operation"
|
| 199 |
+
_Instruction.arg.__doc__ = "Numeric argument to operation (if any), otherwise None"
|
| 200 |
+
_Instruction.argval.__doc__ = "Resolved arg value (if known), otherwise same as arg"
|
| 201 |
+
_Instruction.argrepr.__doc__ = "Human readable description of operation argument"
|
| 202 |
+
_Instruction.offset.__doc__ = "Start index of operation within bytecode sequence"
|
| 203 |
+
_Instruction.starts_line.__doc__ = "Line started by this opcode (if any), otherwise None"
|
| 204 |
+
_Instruction.is_jump_target.__doc__ = "True if other code jumps to here, otherwise False"
|
| 205 |
+
|
| 206 |
+
_OPNAME_WIDTH = 20
|
| 207 |
+
_OPARG_WIDTH = 5
|
| 208 |
+
|
| 209 |
+
class Instruction(_Instruction):
|
| 210 |
+
"""Details for a bytecode operation
|
| 211 |
+
|
| 212 |
+
Defined fields:
|
| 213 |
+
opname - human readable name for operation
|
| 214 |
+
opcode - numeric code for operation
|
| 215 |
+
arg - numeric argument to operation (if any), otherwise None
|
| 216 |
+
argval - resolved arg value (if known), otherwise same as arg
|
| 217 |
+
argrepr - human readable description of operation argument
|
| 218 |
+
offset - start index of operation within bytecode sequence
|
| 219 |
+
starts_line - line started by this opcode (if any), otherwise None
|
| 220 |
+
is_jump_target - True if other code jumps to here, otherwise False
|
| 221 |
+
"""
|
| 222 |
+
|
| 223 |
+
def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4):
|
| 224 |
+
"""Format instruction details for inclusion in disassembly output
|
| 225 |
+
|
| 226 |
+
*lineno_width* sets the width of the line number field (0 omits it)
|
| 227 |
+
*mark_as_current* inserts a '-->' marker arrow as part of the line
|
| 228 |
+
*offset_width* sets the width of the instruction offset field
|
| 229 |
+
"""
|
| 230 |
+
fields = []
|
| 231 |
+
# Column: Source code line number
|
| 232 |
+
if lineno_width:
|
| 233 |
+
if self.starts_line is not None:
|
| 234 |
+
lineno_fmt = "%%%dd" % lineno_width
|
| 235 |
+
fields.append(lineno_fmt % self.starts_line)
|
| 236 |
+
else:
|
| 237 |
+
fields.append(' ' * lineno_width)
|
| 238 |
+
# Column: Current instruction indicator
|
| 239 |
+
if mark_as_current:
|
| 240 |
+
fields.append('-->')
|
| 241 |
+
else:
|
| 242 |
+
fields.append(' ')
|
| 243 |
+
# Column: Jump target marker
|
| 244 |
+
if self.is_jump_target:
|
| 245 |
+
fields.append('>>')
|
| 246 |
+
else:
|
| 247 |
+
fields.append(' ')
|
| 248 |
+
# Column: Instruction offset from start of code sequence
|
| 249 |
+
fields.append(repr(self.offset).rjust(offset_width))
|
| 250 |
+
# Column: Opcode name
|
| 251 |
+
fields.append(self.opname.ljust(_OPNAME_WIDTH))
|
| 252 |
+
# Column: Opcode argument
|
| 253 |
+
if self.arg is not None:
|
| 254 |
+
fields.append(repr(self.arg).rjust(_OPARG_WIDTH))
|
| 255 |
+
# Column: Opcode argument details
|
| 256 |
+
if self.argrepr:
|
| 257 |
+
fields.append('(' + self.argrepr + ')')
|
| 258 |
+
return ' '.join(fields).rstrip()
|
| 259 |
+
|
| 260 |
+
|
| 261 |
+
def get_instructions(x, *, first_line=None):
|
| 262 |
+
"""Iterator for the opcodes in methods, functions or code
|
| 263 |
+
|
| 264 |
+
Generates a series of Instruction named tuples giving the details of
|
| 265 |
+
each operations in the supplied code.
|
| 266 |
+
|
| 267 |
+
If *first_line* is not None, it indicates the line number that should
|
| 268 |
+
be reported for the first source line in the disassembled code.
|
| 269 |
+
Otherwise, the source line information (if any) is taken directly from
|
| 270 |
+
the disassembled code object.
|
| 271 |
+
"""
|
| 272 |
+
co = _get_code_object(x)
|
| 273 |
+
cell_names = co.co_cellvars + co.co_freevars
|
| 274 |
+
linestarts = dict(findlinestarts(co))
|
| 275 |
+
if first_line is not None:
|
| 276 |
+
line_offset = first_line - co.co_firstlineno
|
| 277 |
+
else:
|
| 278 |
+
line_offset = 0
|
| 279 |
+
return _get_instructions_bytes(co.co_code, co.co_varnames, co.co_names,
|
| 280 |
+
co.co_consts, cell_names, linestarts,
|
| 281 |
+
line_offset)
|
| 282 |
+
|
| 283 |
+
def _get_const_info(const_index, const_list):
|
| 284 |
+
"""Helper to get optional details about const references
|
| 285 |
+
|
| 286 |
+
Returns the dereferenced constant and its repr if the constant
|
| 287 |
+
list is defined.
|
| 288 |
+
Otherwise returns the constant index and its repr().
|
| 289 |
+
"""
|
| 290 |
+
argval = const_index
|
| 291 |
+
if const_list is not None:
|
| 292 |
+
argval = const_list[const_index]
|
| 293 |
+
return argval, repr(argval)
|
| 294 |
+
|
| 295 |
+
def _get_name_info(name_index, name_list):
|
| 296 |
+
"""Helper to get optional details about named references
|
| 297 |
+
|
| 298 |
+
Returns the dereferenced name as both value and repr if the name
|
| 299 |
+
list is defined.
|
| 300 |
+
Otherwise returns the name index and its repr().
|
| 301 |
+
"""
|
| 302 |
+
argval = name_index
|
| 303 |
+
if name_list is not None:
|
| 304 |
+
argval = name_list[name_index]
|
| 305 |
+
argrepr = argval
|
| 306 |
+
else:
|
| 307 |
+
argrepr = repr(argval)
|
| 308 |
+
return argval, argrepr
|
| 309 |
+
|
| 310 |
+
|
| 311 |
+
def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
|
| 312 |
+
cells=None, linestarts=None, line_offset=0):
|
| 313 |
+
"""Iterate over the instructions in a bytecode string.
|
| 314 |
+
|
| 315 |
+
Generates a sequence of Instruction namedtuples giving the details of each
|
| 316 |
+
opcode. Additional information about the code's runtime environment
|
| 317 |
+
(e.g. variable names, constants) can be specified using optional
|
| 318 |
+
arguments.
|
| 319 |
+
|
| 320 |
+
"""
|
| 321 |
+
labels = findlabels(code)
|
| 322 |
+
starts_line = None
|
| 323 |
+
for offset, op, arg in _unpack_opargs(code):
|
| 324 |
+
if linestarts is not None:
|
| 325 |
+
starts_line = linestarts.get(offset, None)
|
| 326 |
+
if starts_line is not None:
|
| 327 |
+
starts_line += line_offset
|
| 328 |
+
is_jump_target = offset in labels
|
| 329 |
+
argval = None
|
| 330 |
+
argrepr = ''
|
| 331 |
+
if arg is not None:
|
| 332 |
+
# Set argval to the dereferenced value of the argument when
|
| 333 |
+
# available, and argrepr to the string representation of argval.
|
| 334 |
+
# _disassemble_bytes needs the string repr of the
|
| 335 |
+
# raw name index for LOAD_GLOBAL, LOAD_CONST, etc.
|
| 336 |
+
argval = arg
|
| 337 |
+
if op in hasconst:
|
| 338 |
+
argval, argrepr = _get_const_info(arg, constants)
|
| 339 |
+
elif op in hasname:
|
| 340 |
+
argval, argrepr = _get_name_info(arg, names)
|
| 341 |
+
elif op in hasjrel:
|
| 342 |
+
argval = offset + 2 + arg
|
| 343 |
+
argrepr = "to " + repr(argval)
|
| 344 |
+
elif op in haslocal:
|
| 345 |
+
argval, argrepr = _get_name_info(arg, varnames)
|
| 346 |
+
elif op in hascompare:
|
| 347 |
+
argval = cmp_op[arg]
|
| 348 |
+
argrepr = argval
|
| 349 |
+
elif op in hasfree:
|
| 350 |
+
argval, argrepr = _get_name_info(arg, cells)
|
| 351 |
+
elif op == FORMAT_VALUE:
|
| 352 |
+
argval, argrepr = FORMAT_VALUE_CONVERTERS[arg & 0x3]
|
| 353 |
+
argval = (argval, bool(arg & 0x4))
|
| 354 |
+
if argval[1]:
|
| 355 |
+
if argrepr:
|
| 356 |
+
argrepr += ', '
|
| 357 |
+
argrepr += 'with format'
|
| 358 |
+
elif op == MAKE_FUNCTION:
|
| 359 |
+
argrepr = ', '.join(s for i, s in enumerate(MAKE_FUNCTION_FLAGS)
|
| 360 |
+
if arg & (1<<i))
|
| 361 |
+
yield Instruction(opname[op], op,
|
| 362 |
+
arg, argval, argrepr,
|
| 363 |
+
offset, starts_line, is_jump_target)
|
| 364 |
+
|
| 365 |
+
def disassemble(co, lasti=-1, *, file=None):
|
| 366 |
+
"""Disassemble a code object."""
|
| 367 |
+
cell_names = co.co_cellvars + co.co_freevars
|
| 368 |
+
linestarts = dict(findlinestarts(co))
|
| 369 |
+
_disassemble_bytes(co.co_code, lasti, co.co_varnames, co.co_names,
|
| 370 |
+
co.co_consts, cell_names, linestarts, file=file)
|
| 371 |
+
|
| 372 |
+
def _disassemble_recursive(co, *, file=None, depth=None):
|
| 373 |
+
disassemble(co, file=file)
|
| 374 |
+
if depth is None or depth > 0:
|
| 375 |
+
if depth is not None:
|
| 376 |
+
depth = depth - 1
|
| 377 |
+
for x in co.co_consts:
|
| 378 |
+
if hasattr(x, 'co_code'):
|
| 379 |
+
print(file=file)
|
| 380 |
+
print("Disassembly of %r:" % (x,), file=file)
|
| 381 |
+
_disassemble_recursive(x, file=file, depth=depth)
|
| 382 |
+
|
| 383 |
+
def _disassemble_bytes(code, lasti=-1, varnames=None, names=None,
|
| 384 |
+
constants=None, cells=None, linestarts=None,
|
| 385 |
+
*, file=None, line_offset=0):
|
| 386 |
+
# Omit the line number column entirely if we have no line number info
|
| 387 |
+
show_lineno = linestarts is not None
|
| 388 |
+
if show_lineno:
|
| 389 |
+
maxlineno = max(linestarts.values()) + line_offset
|
| 390 |
+
if maxlineno >= 1000:
|
| 391 |
+
lineno_width = len(str(maxlineno))
|
| 392 |
+
else:
|
| 393 |
+
lineno_width = 3
|
| 394 |
+
else:
|
| 395 |
+
lineno_width = 0
|
| 396 |
+
maxoffset = len(code) - 2
|
| 397 |
+
if maxoffset >= 10000:
|
| 398 |
+
offset_width = len(str(maxoffset))
|
| 399 |
+
else:
|
| 400 |
+
offset_width = 4
|
| 401 |
+
for instr in _get_instructions_bytes(code, varnames, names,
|
| 402 |
+
constants, cells, linestarts,
|
| 403 |
+
line_offset=line_offset):
|
| 404 |
+
new_source_line = (show_lineno and
|
| 405 |
+
instr.starts_line is not None and
|
| 406 |
+
instr.offset > 0)
|
| 407 |
+
if new_source_line:
|
| 408 |
+
print(file=file)
|
| 409 |
+
is_current_instr = instr.offset == lasti
|
| 410 |
+
print(instr._disassemble(lineno_width, is_current_instr, offset_width),
|
| 411 |
+
file=file)
|
| 412 |
+
|
| 413 |
+
def _disassemble_str(source, **kwargs):
|
| 414 |
+
"""Compile the source string, then disassemble the code object."""
|
| 415 |
+
_disassemble_recursive(_try_compile(source, '<dis>'), **kwargs)
|
| 416 |
+
|
| 417 |
+
disco = disassemble # XXX For backwards compatibility
|
| 418 |
+
|
| 419 |
+
def _unpack_opargs(code):
|
| 420 |
+
extended_arg = 0
|
| 421 |
+
for i in range(0, len(code), 2):
|
| 422 |
+
op = code[i]
|
| 423 |
+
if op >= HAVE_ARGUMENT:
|
| 424 |
+
arg = code[i+1] | extended_arg
|
| 425 |
+
extended_arg = (arg << 8) if op == EXTENDED_ARG else 0
|
| 426 |
+
else:
|
| 427 |
+
arg = None
|
| 428 |
+
yield (i, op, arg)
|
| 429 |
+
|
| 430 |
+
def findlabels(code):
|
| 431 |
+
"""Detect all offsets in a byte code which are jump targets.
|
| 432 |
+
|
| 433 |
+
Return the list of offsets.
|
| 434 |
+
|
| 435 |
+
"""
|
| 436 |
+
labels = []
|
| 437 |
+
for offset, op, arg in _unpack_opargs(code):
|
| 438 |
+
if arg is not None:
|
| 439 |
+
if op in hasjrel:
|
| 440 |
+
label = offset + 2 + arg
|
| 441 |
+
elif op in hasjabs:
|
| 442 |
+
label = arg
|
| 443 |
+
else:
|
| 444 |
+
continue
|
| 445 |
+
if label not in labels:
|
| 446 |
+
labels.append(label)
|
| 447 |
+
return labels
|
| 448 |
+
|
| 449 |
+
def findlinestarts(code):
|
| 450 |
+
"""Find the offsets in a byte code which are start of lines in the source.
|
| 451 |
+
|
| 452 |
+
Generate pairs (offset, lineno) as described in Python/compile.c.
|
| 453 |
+
|
| 454 |
+
"""
|
| 455 |
+
byte_increments = code.co_lnotab[0::2]
|
| 456 |
+
line_increments = code.co_lnotab[1::2]
|
| 457 |
+
bytecode_len = len(code.co_code)
|
| 458 |
+
|
| 459 |
+
lastlineno = None
|
| 460 |
+
lineno = code.co_firstlineno
|
| 461 |
+
addr = 0
|
| 462 |
+
for byte_incr, line_incr in zip(byte_increments, line_increments):
|
| 463 |
+
if byte_incr:
|
| 464 |
+
if lineno != lastlineno:
|
| 465 |
+
yield (addr, lineno)
|
| 466 |
+
lastlineno = lineno
|
| 467 |
+
addr += byte_incr
|
| 468 |
+
if addr >= bytecode_len:
|
| 469 |
+
# The rest of the lnotab byte offsets are past the end of
|
| 470 |
+
# the bytecode, so the lines were optimized away.
|
| 471 |
+
return
|
| 472 |
+
if line_incr >= 0x80:
|
| 473 |
+
# line_increments is an array of 8-bit signed integers
|
| 474 |
+
line_incr -= 0x100
|
| 475 |
+
lineno += line_incr
|
| 476 |
+
if lineno != lastlineno:
|
| 477 |
+
yield (addr, lineno)
|
| 478 |
+
|
| 479 |
+
class Bytecode:
|
| 480 |
+
"""The bytecode operations of a piece of code
|
| 481 |
+
|
| 482 |
+
Instantiate this with a function, method, other compiled object, string of
|
| 483 |
+
code, or a code object (as returned by compile()).
|
| 484 |
+
|
| 485 |
+
Iterating over this yields the bytecode operations as Instruction instances.
|
| 486 |
+
"""
|
| 487 |
+
def __init__(self, x, *, first_line=None, current_offset=None):
|
| 488 |
+
self.codeobj = co = _get_code_object(x)
|
| 489 |
+
if first_line is None:
|
| 490 |
+
self.first_line = co.co_firstlineno
|
| 491 |
+
self._line_offset = 0
|
| 492 |
+
else:
|
| 493 |
+
self.first_line = first_line
|
| 494 |
+
self._line_offset = first_line - co.co_firstlineno
|
| 495 |
+
self._cell_names = co.co_cellvars + co.co_freevars
|
| 496 |
+
self._linestarts = dict(findlinestarts(co))
|
| 497 |
+
self._original_object = x
|
| 498 |
+
self.current_offset = current_offset
|
| 499 |
+
|
| 500 |
+
def __iter__(self):
|
| 501 |
+
co = self.codeobj
|
| 502 |
+
return _get_instructions_bytes(co.co_code, co.co_varnames, co.co_names,
|
| 503 |
+
co.co_consts, self._cell_names,
|
| 504 |
+
self._linestarts,
|
| 505 |
+
line_offset=self._line_offset)
|
| 506 |
+
|
| 507 |
+
def __repr__(self):
|
| 508 |
+
return "{}({!r})".format(self.__class__.__name__,
|
| 509 |
+
self._original_object)
|
| 510 |
+
|
| 511 |
+
@classmethod
|
| 512 |
+
def from_traceback(cls, tb):
|
| 513 |
+
""" Construct a Bytecode from the given traceback """
|
| 514 |
+
while tb.tb_next:
|
| 515 |
+
tb = tb.tb_next
|
| 516 |
+
return cls(tb.tb_frame.f_code, current_offset=tb.tb_lasti)
|
| 517 |
+
|
| 518 |
+
def info(self):
|
| 519 |
+
"""Return formatted information about the code object."""
|
| 520 |
+
return _format_code_info(self.codeobj)
|
| 521 |
+
|
| 522 |
+
def dis(self):
|
| 523 |
+
"""Return a formatted view of the bytecode operations."""
|
| 524 |
+
co = self.codeobj
|
| 525 |
+
if self.current_offset is not None:
|
| 526 |
+
offset = self.current_offset
|
| 527 |
+
else:
|
| 528 |
+
offset = -1
|
| 529 |
+
with io.StringIO() as output:
|
| 530 |
+
_disassemble_bytes(co.co_code, varnames=co.co_varnames,
|
| 531 |
+
names=co.co_names, constants=co.co_consts,
|
| 532 |
+
cells=self._cell_names,
|
| 533 |
+
linestarts=self._linestarts,
|
| 534 |
+
line_offset=self._line_offset,
|
| 535 |
+
file=output,
|
| 536 |
+
lasti=offset)
|
| 537 |
+
return output.getvalue()
|
| 538 |
+
|
| 539 |
+
|
| 540 |
+
def _test():
|
| 541 |
+
"""Simple test program to disassemble a file."""
|
| 542 |
+
import argparse
|
| 543 |
+
|
| 544 |
+
parser = argparse.ArgumentParser()
|
| 545 |
+
parser.add_argument('infile', type=argparse.FileType('rb'), nargs='?', default='-')
|
| 546 |
+
args = parser.parse_args()
|
| 547 |
+
with args.infile as infile:
|
| 548 |
+
source = infile.read()
|
| 549 |
+
code = compile(source, args.infile.name, "exec")
|
| 550 |
+
dis(code)
|
| 551 |
+
|
| 552 |
+
if __name__ == "__main__":
|
| 553 |
+
_test()
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/enum.py
ADDED
|
@@ -0,0 +1,1018 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
from types import MappingProxyType, DynamicClassAttribute
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
__all__ = [
|
| 6 |
+
'EnumMeta',
|
| 7 |
+
'Enum', 'IntEnum', 'Flag', 'IntFlag',
|
| 8 |
+
'auto', 'unique',
|
| 9 |
+
]
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def _is_descriptor(obj):
|
| 13 |
+
"""
|
| 14 |
+
Returns True if obj is a descriptor, False otherwise.
|
| 15 |
+
"""
|
| 16 |
+
return (
|
| 17 |
+
hasattr(obj, '__get__') or
|
| 18 |
+
hasattr(obj, '__set__') or
|
| 19 |
+
hasattr(obj, '__delete__')
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
def _is_dunder(name):
|
| 23 |
+
"""
|
| 24 |
+
Returns True if a __dunder__ name, False otherwise.
|
| 25 |
+
"""
|
| 26 |
+
return (
|
| 27 |
+
len(name) > 4 and
|
| 28 |
+
name[:2] == name[-2:] == '__' and
|
| 29 |
+
name[2] != '_' and
|
| 30 |
+
name[-3] != '_'
|
| 31 |
+
)
|
| 32 |
+
|
| 33 |
+
def _is_sunder(name):
|
| 34 |
+
"""
|
| 35 |
+
Returns True if a _sunder_ name, False otherwise.
|
| 36 |
+
"""
|
| 37 |
+
return (
|
| 38 |
+
len(name) > 2 and
|
| 39 |
+
name[0] == name[-1] == '_' and
|
| 40 |
+
name[1:2] != '_' and
|
| 41 |
+
name[-2:-1] != '_'
|
| 42 |
+
)
|
| 43 |
+
|
| 44 |
+
def _make_class_unpicklable(cls):
|
| 45 |
+
"""
|
| 46 |
+
Make the given class un-picklable.
|
| 47 |
+
"""
|
| 48 |
+
def _break_on_call_reduce(self, proto):
|
| 49 |
+
raise TypeError('%r cannot be pickled' % self)
|
| 50 |
+
cls.__reduce_ex__ = _break_on_call_reduce
|
| 51 |
+
cls.__module__ = '<unknown>'
|
| 52 |
+
|
| 53 |
+
_auto_null = object()
|
| 54 |
+
class auto:
|
| 55 |
+
"""
|
| 56 |
+
Instances are replaced with an appropriate value in Enum class suites.
|
| 57 |
+
"""
|
| 58 |
+
value = _auto_null
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
class _EnumDict(dict):
|
| 62 |
+
"""
|
| 63 |
+
Track enum member order and ensure member names are not reused.
|
| 64 |
+
|
| 65 |
+
EnumMeta will use the names found in self._member_names as the
|
| 66 |
+
enumeration member names.
|
| 67 |
+
"""
|
| 68 |
+
def __init__(self):
|
| 69 |
+
super().__init__()
|
| 70 |
+
self._member_names = []
|
| 71 |
+
self._last_values = []
|
| 72 |
+
self._ignore = []
|
| 73 |
+
self._auto_called = False
|
| 74 |
+
|
| 75 |
+
def __setitem__(self, key, value):
|
| 76 |
+
"""
|
| 77 |
+
Changes anything not dundered or not a descriptor.
|
| 78 |
+
|
| 79 |
+
If an enum member name is used twice, an error is raised; duplicate
|
| 80 |
+
values are not checked for.
|
| 81 |
+
|
| 82 |
+
Single underscore (sunder) names are reserved.
|
| 83 |
+
"""
|
| 84 |
+
if _is_sunder(key):
|
| 85 |
+
if key not in (
|
| 86 |
+
'_order_', '_create_pseudo_member_',
|
| 87 |
+
'_generate_next_value_', '_missing_', '_ignore_',
|
| 88 |
+
):
|
| 89 |
+
raise ValueError('_names_ are reserved for future Enum use')
|
| 90 |
+
if key == '_generate_next_value_':
|
| 91 |
+
# check if members already defined as auto()
|
| 92 |
+
if self._auto_called:
|
| 93 |
+
raise TypeError("_generate_next_value_ must be defined before members")
|
| 94 |
+
setattr(self, '_generate_next_value', value)
|
| 95 |
+
elif key == '_ignore_':
|
| 96 |
+
if isinstance(value, str):
|
| 97 |
+
value = value.replace(',',' ').split()
|
| 98 |
+
else:
|
| 99 |
+
value = list(value)
|
| 100 |
+
self._ignore = value
|
| 101 |
+
already = set(value) & set(self._member_names)
|
| 102 |
+
if already:
|
| 103 |
+
raise ValueError(
|
| 104 |
+
'_ignore_ cannot specify already set names: %r'
|
| 105 |
+
% (already, )
|
| 106 |
+
)
|
| 107 |
+
elif _is_dunder(key):
|
| 108 |
+
if key == '__order__':
|
| 109 |
+
key = '_order_'
|
| 110 |
+
elif key in self._member_names:
|
| 111 |
+
# descriptor overwriting an enum?
|
| 112 |
+
raise TypeError('Attempted to reuse key: %r' % key)
|
| 113 |
+
elif key in self._ignore:
|
| 114 |
+
pass
|
| 115 |
+
elif not _is_descriptor(value):
|
| 116 |
+
if key in self:
|
| 117 |
+
# enum overwriting a descriptor?
|
| 118 |
+
raise TypeError('%r already defined as: %r' % (key, self[key]))
|
| 119 |
+
if isinstance(value, auto):
|
| 120 |
+
if value.value == _auto_null:
|
| 121 |
+
value.value = self._generate_next_value(
|
| 122 |
+
key,
|
| 123 |
+
1,
|
| 124 |
+
len(self._member_names),
|
| 125 |
+
self._last_values[:],
|
| 126 |
+
)
|
| 127 |
+
self._auto_called = True
|
| 128 |
+
value = value.value
|
| 129 |
+
self._member_names.append(key)
|
| 130 |
+
self._last_values.append(value)
|
| 131 |
+
super().__setitem__(key, value)
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
# Dummy value for Enum as EnumMeta explicitly checks for it, but of course
|
| 135 |
+
# until EnumMeta finishes running the first time the Enum class doesn't exist.
|
| 136 |
+
# This is also why there are checks in EnumMeta like `if Enum is not None`
|
| 137 |
+
Enum = None
|
| 138 |
+
|
| 139 |
+
class EnumMeta(type):
|
| 140 |
+
"""
|
| 141 |
+
Metaclass for Enum
|
| 142 |
+
"""
|
| 143 |
+
@classmethod
|
| 144 |
+
def __prepare__(metacls, cls, bases):
|
| 145 |
+
# check that previous enum members do not exist
|
| 146 |
+
metacls._check_for_existing_members(cls, bases)
|
| 147 |
+
# create the namespace dict
|
| 148 |
+
enum_dict = _EnumDict()
|
| 149 |
+
# inherit previous flags and _generate_next_value_ function
|
| 150 |
+
member_type, first_enum = metacls._get_mixins_(cls, bases)
|
| 151 |
+
if first_enum is not None:
|
| 152 |
+
enum_dict['_generate_next_value_'] = getattr(
|
| 153 |
+
first_enum, '_generate_next_value_', None,
|
| 154 |
+
)
|
| 155 |
+
return enum_dict
|
| 156 |
+
|
| 157 |
+
def __new__(metacls, cls, bases, classdict):
|
| 158 |
+
# an Enum class is final once enumeration items have been defined; it
|
| 159 |
+
# cannot be mixed with other types (int, float, etc.) if it has an
|
| 160 |
+
# inherited __new__ unless a new __new__ is defined (or the resulting
|
| 161 |
+
# class will fail).
|
| 162 |
+
#
|
| 163 |
+
# remove any keys listed in _ignore_
|
| 164 |
+
classdict.setdefault('_ignore_', []).append('_ignore_')
|
| 165 |
+
ignore = classdict['_ignore_']
|
| 166 |
+
for key in ignore:
|
| 167 |
+
classdict.pop(key, None)
|
| 168 |
+
member_type, first_enum = metacls._get_mixins_(cls, bases)
|
| 169 |
+
__new__, save_new, use_args = metacls._find_new_(
|
| 170 |
+
classdict, member_type, first_enum,
|
| 171 |
+
)
|
| 172 |
+
|
| 173 |
+
# save enum items into separate mapping so they don't get baked into
|
| 174 |
+
# the new class
|
| 175 |
+
enum_members = {k: classdict[k] for k in classdict._member_names}
|
| 176 |
+
for name in classdict._member_names:
|
| 177 |
+
del classdict[name]
|
| 178 |
+
|
| 179 |
+
# adjust the sunders
|
| 180 |
+
_order_ = classdict.pop('_order_', None)
|
| 181 |
+
|
| 182 |
+
# check for illegal enum names (any others?)
|
| 183 |
+
invalid_names = set(enum_members) & {'mro', ''}
|
| 184 |
+
if invalid_names:
|
| 185 |
+
raise ValueError('Invalid enum member name: {0}'.format(
|
| 186 |
+
','.join(invalid_names)))
|
| 187 |
+
|
| 188 |
+
# create a default docstring if one has not been provided
|
| 189 |
+
if '__doc__' not in classdict:
|
| 190 |
+
classdict['__doc__'] = 'An enumeration.'
|
| 191 |
+
|
| 192 |
+
# create our new Enum type
|
| 193 |
+
enum_class = super().__new__(metacls, cls, bases, classdict)
|
| 194 |
+
enum_class._member_names_ = [] # names in definition order
|
| 195 |
+
enum_class._member_map_ = {} # name->value map
|
| 196 |
+
enum_class._member_type_ = member_type
|
| 197 |
+
|
| 198 |
+
# save DynamicClassAttribute attributes from super classes so we know
|
| 199 |
+
# if we can take the shortcut of storing members in the class dict
|
| 200 |
+
dynamic_attributes = {
|
| 201 |
+
k for c in enum_class.mro()
|
| 202 |
+
for k, v in c.__dict__.items()
|
| 203 |
+
if isinstance(v, DynamicClassAttribute)
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
# Reverse value->name map for hashable values.
|
| 207 |
+
enum_class._value2member_map_ = {}
|
| 208 |
+
|
| 209 |
+
# If a custom type is mixed into the Enum, and it does not know how
|
| 210 |
+
# to pickle itself, pickle.dumps will succeed but pickle.loads will
|
| 211 |
+
# fail. Rather than have the error show up later and possibly far
|
| 212 |
+
# from the source, sabotage the pickle protocol for this class so
|
| 213 |
+
# that pickle.dumps also fails.
|
| 214 |
+
#
|
| 215 |
+
# However, if the new class implements its own __reduce_ex__, do not
|
| 216 |
+
# sabotage -- it's on them to make sure it works correctly. We use
|
| 217 |
+
# __reduce_ex__ instead of any of the others as it is preferred by
|
| 218 |
+
# pickle over __reduce__, and it handles all pickle protocols.
|
| 219 |
+
if '__reduce_ex__' not in classdict:
|
| 220 |
+
if member_type is not object:
|
| 221 |
+
methods = ('__getnewargs_ex__', '__getnewargs__',
|
| 222 |
+
'__reduce_ex__', '__reduce__')
|
| 223 |
+
if not any(m in member_type.__dict__ for m in methods):
|
| 224 |
+
_make_class_unpicklable(enum_class)
|
| 225 |
+
|
| 226 |
+
# instantiate them, checking for duplicates as we go
|
| 227 |
+
# we instantiate first instead of checking for duplicates first in case
|
| 228 |
+
# a custom __new__ is doing something funky with the values -- such as
|
| 229 |
+
# auto-numbering ;)
|
| 230 |
+
for member_name in classdict._member_names:
|
| 231 |
+
value = enum_members[member_name]
|
| 232 |
+
if not isinstance(value, tuple):
|
| 233 |
+
args = (value, )
|
| 234 |
+
else:
|
| 235 |
+
args = value
|
| 236 |
+
if member_type is tuple: # special case for tuple enums
|
| 237 |
+
args = (args, ) # wrap it one more time
|
| 238 |
+
if not use_args:
|
| 239 |
+
enum_member = __new__(enum_class)
|
| 240 |
+
if not hasattr(enum_member, '_value_'):
|
| 241 |
+
enum_member._value_ = value
|
| 242 |
+
else:
|
| 243 |
+
enum_member = __new__(enum_class, *args)
|
| 244 |
+
if not hasattr(enum_member, '_value_'):
|
| 245 |
+
if member_type is object:
|
| 246 |
+
enum_member._value_ = value
|
| 247 |
+
else:
|
| 248 |
+
enum_member._value_ = member_type(*args)
|
| 249 |
+
value = enum_member._value_
|
| 250 |
+
enum_member._name_ = member_name
|
| 251 |
+
enum_member.__objclass__ = enum_class
|
| 252 |
+
enum_member.__init__(*args)
|
| 253 |
+
# If another member with the same value was already defined, the
|
| 254 |
+
# new member becomes an alias to the existing one.
|
| 255 |
+
for name, canonical_member in enum_class._member_map_.items():
|
| 256 |
+
if canonical_member._value_ == enum_member._value_:
|
| 257 |
+
enum_member = canonical_member
|
| 258 |
+
break
|
| 259 |
+
else:
|
| 260 |
+
# Aliases don't appear in member names (only in __members__).
|
| 261 |
+
enum_class._member_names_.append(member_name)
|
| 262 |
+
# performance boost for any member that would not shadow
|
| 263 |
+
# a DynamicClassAttribute
|
| 264 |
+
if member_name not in dynamic_attributes:
|
| 265 |
+
setattr(enum_class, member_name, enum_member)
|
| 266 |
+
# now add to _member_map_
|
| 267 |
+
enum_class._member_map_[member_name] = enum_member
|
| 268 |
+
try:
|
| 269 |
+
# This may fail if value is not hashable. We can't add the value
|
| 270 |
+
# to the map, and by-value lookups for this value will be
|
| 271 |
+
# linear.
|
| 272 |
+
enum_class._value2member_map_[value] = enum_member
|
| 273 |
+
except TypeError:
|
| 274 |
+
pass
|
| 275 |
+
|
| 276 |
+
# double check that repr and friends are not the mixin's or various
|
| 277 |
+
# things break (such as pickle)
|
| 278 |
+
# however, if the method is defined in the Enum itself, don't replace
|
| 279 |
+
# it
|
| 280 |
+
for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'):
|
| 281 |
+
if name in classdict:
|
| 282 |
+
continue
|
| 283 |
+
class_method = getattr(enum_class, name)
|
| 284 |
+
obj_method = getattr(member_type, name, None)
|
| 285 |
+
enum_method = getattr(first_enum, name, None)
|
| 286 |
+
if obj_method is not None and obj_method is class_method:
|
| 287 |
+
setattr(enum_class, name, enum_method)
|
| 288 |
+
|
| 289 |
+
# replace any other __new__ with our own (as long as Enum is not None,
|
| 290 |
+
# anyway) -- again, this is to support pickle
|
| 291 |
+
if Enum is not None:
|
| 292 |
+
# if the user defined their own __new__, save it before it gets
|
| 293 |
+
# clobbered in case they subclass later
|
| 294 |
+
if save_new:
|
| 295 |
+
enum_class.__new_member__ = __new__
|
| 296 |
+
enum_class.__new__ = Enum.__new__
|
| 297 |
+
|
| 298 |
+
# py3 support for definition order (helps keep py2/py3 code in sync)
|
| 299 |
+
if _order_ is not None:
|
| 300 |
+
if isinstance(_order_, str):
|
| 301 |
+
_order_ = _order_.replace(',', ' ').split()
|
| 302 |
+
if _order_ != enum_class._member_names_:
|
| 303 |
+
raise TypeError('member order does not match _order_')
|
| 304 |
+
|
| 305 |
+
return enum_class
|
| 306 |
+
|
| 307 |
+
def __bool__(self):
|
| 308 |
+
"""
|
| 309 |
+
classes/types should always be True.
|
| 310 |
+
"""
|
| 311 |
+
return True
|
| 312 |
+
|
| 313 |
+
def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1):
|
| 314 |
+
"""
|
| 315 |
+
Either returns an existing member, or creates a new enum class.
|
| 316 |
+
|
| 317 |
+
This method is used both when an enum class is given a value to match
|
| 318 |
+
to an enumeration member (i.e. Color(3)) and for the functional API
|
| 319 |
+
(i.e. Color = Enum('Color', names='RED GREEN BLUE')).
|
| 320 |
+
|
| 321 |
+
When used for the functional API:
|
| 322 |
+
|
| 323 |
+
`value` will be the name of the new class.
|
| 324 |
+
|
| 325 |
+
`names` should be either a string of white-space/comma delimited names
|
| 326 |
+
(values will start at `start`), or an iterator/mapping of name, value pairs.
|
| 327 |
+
|
| 328 |
+
`module` should be set to the module this class is being created in;
|
| 329 |
+
if it is not set, an attempt to find that module will be made, but if
|
| 330 |
+
it fails the class will not be picklable.
|
| 331 |
+
|
| 332 |
+
`qualname` should be set to the actual location this class can be found
|
| 333 |
+
at in its module; by default it is set to the global scope. If this is
|
| 334 |
+
not correct, unpickling will fail in some circumstances.
|
| 335 |
+
|
| 336 |
+
`type`, if set, will be mixed in as the first base class.
|
| 337 |
+
"""
|
| 338 |
+
if names is None: # simple value lookup
|
| 339 |
+
return cls.__new__(cls, value)
|
| 340 |
+
# otherwise, functional API: we're creating a new Enum type
|
| 341 |
+
return cls._create_(
|
| 342 |
+
value,
|
| 343 |
+
names,
|
| 344 |
+
module=module,
|
| 345 |
+
qualname=qualname,
|
| 346 |
+
type=type,
|
| 347 |
+
start=start,
|
| 348 |
+
)
|
| 349 |
+
|
| 350 |
+
def __contains__(cls, member):
|
| 351 |
+
if not isinstance(member, Enum):
|
| 352 |
+
raise TypeError(
|
| 353 |
+
"unsupported operand type(s) for 'in': '%s' and '%s'" % (
|
| 354 |
+
type(member).__qualname__, cls.__class__.__qualname__))
|
| 355 |
+
return isinstance(member, cls) and member._name_ in cls._member_map_
|
| 356 |
+
|
| 357 |
+
def __delattr__(cls, attr):
|
| 358 |
+
# nicer error message when someone tries to delete an attribute
|
| 359 |
+
# (see issue19025).
|
| 360 |
+
if attr in cls._member_map_:
|
| 361 |
+
raise AttributeError("%s: cannot delete Enum member." % cls.__name__)
|
| 362 |
+
super().__delattr__(attr)
|
| 363 |
+
|
| 364 |
+
def __dir__(self):
|
| 365 |
+
return (
|
| 366 |
+
['__class__', '__doc__', '__members__', '__module__']
|
| 367 |
+
+ self._member_names_
|
| 368 |
+
)
|
| 369 |
+
|
| 370 |
+
def __getattr__(cls, name):
|
| 371 |
+
"""
|
| 372 |
+
Return the enum member matching `name`
|
| 373 |
+
|
| 374 |
+
We use __getattr__ instead of descriptors or inserting into the enum
|
| 375 |
+
class' __dict__ in order to support `name` and `value` being both
|
| 376 |
+
properties for enum members (which live in the class' __dict__) and
|
| 377 |
+
enum members themselves.
|
| 378 |
+
"""
|
| 379 |
+
if _is_dunder(name):
|
| 380 |
+
raise AttributeError(name)
|
| 381 |
+
try:
|
| 382 |
+
return cls._member_map_[name]
|
| 383 |
+
except KeyError:
|
| 384 |
+
raise AttributeError(name) from None
|
| 385 |
+
|
| 386 |
+
def __getitem__(cls, name):
|
| 387 |
+
return cls._member_map_[name]
|
| 388 |
+
|
| 389 |
+
def __iter__(cls):
|
| 390 |
+
"""
|
| 391 |
+
Returns members in definition order.
|
| 392 |
+
"""
|
| 393 |
+
return (cls._member_map_[name] for name in cls._member_names_)
|
| 394 |
+
|
| 395 |
+
def __len__(cls):
|
| 396 |
+
return len(cls._member_names_)
|
| 397 |
+
|
| 398 |
+
@property
|
| 399 |
+
def __members__(cls):
|
| 400 |
+
"""
|
| 401 |
+
Returns a mapping of member name->value.
|
| 402 |
+
|
| 403 |
+
This mapping lists all enum members, including aliases. Note that this
|
| 404 |
+
is a read-only view of the internal mapping.
|
| 405 |
+
"""
|
| 406 |
+
return MappingProxyType(cls._member_map_)
|
| 407 |
+
|
| 408 |
+
def __repr__(cls):
|
| 409 |
+
return "<enum %r>" % cls.__name__
|
| 410 |
+
|
| 411 |
+
def __reversed__(cls):
|
| 412 |
+
"""
|
| 413 |
+
Returns members in reverse definition order.
|
| 414 |
+
"""
|
| 415 |
+
return (cls._member_map_[name] for name in reversed(cls._member_names_))
|
| 416 |
+
|
| 417 |
+
def __setattr__(cls, name, value):
|
| 418 |
+
"""
|
| 419 |
+
Block attempts to reassign Enum members.
|
| 420 |
+
|
| 421 |
+
A simple assignment to the class namespace only changes one of the
|
| 422 |
+
several possible ways to get an Enum member from the Enum class,
|
| 423 |
+
resulting in an inconsistent Enumeration.
|
| 424 |
+
"""
|
| 425 |
+
member_map = cls.__dict__.get('_member_map_', {})
|
| 426 |
+
if name in member_map:
|
| 427 |
+
raise AttributeError('Cannot reassign members.')
|
| 428 |
+
super().__setattr__(name, value)
|
| 429 |
+
|
| 430 |
+
def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, start=1):
|
| 431 |
+
"""
|
| 432 |
+
Convenience method to create a new Enum class.
|
| 433 |
+
|
| 434 |
+
`names` can be:
|
| 435 |
+
|
| 436 |
+
* A string containing member names, separated either with spaces or
|
| 437 |
+
commas. Values are incremented by 1 from `start`.
|
| 438 |
+
* An iterable of member names. Values are incremented by 1 from `start`.
|
| 439 |
+
* An iterable of (member name, value) pairs.
|
| 440 |
+
* A mapping of member name -> value pairs.
|
| 441 |
+
"""
|
| 442 |
+
metacls = cls.__class__
|
| 443 |
+
bases = (cls, ) if type is None else (type, cls)
|
| 444 |
+
_, first_enum = cls._get_mixins_(cls, bases)
|
| 445 |
+
classdict = metacls.__prepare__(class_name, bases)
|
| 446 |
+
|
| 447 |
+
# special processing needed for names?
|
| 448 |
+
if isinstance(names, str):
|
| 449 |
+
names = names.replace(',', ' ').split()
|
| 450 |
+
if isinstance(names, (tuple, list)) and names and isinstance(names[0], str):
|
| 451 |
+
original_names, names = names, []
|
| 452 |
+
last_values = []
|
| 453 |
+
for count, name in enumerate(original_names):
|
| 454 |
+
value = first_enum._generate_next_value_(name, start, count, last_values[:])
|
| 455 |
+
last_values.append(value)
|
| 456 |
+
names.append((name, value))
|
| 457 |
+
|
| 458 |
+
# Here, names is either an iterable of (name, value) or a mapping.
|
| 459 |
+
for item in names:
|
| 460 |
+
if isinstance(item, str):
|
| 461 |
+
member_name, member_value = item, names[item]
|
| 462 |
+
else:
|
| 463 |
+
member_name, member_value = item
|
| 464 |
+
classdict[member_name] = member_value
|
| 465 |
+
enum_class = metacls.__new__(metacls, class_name, bases, classdict)
|
| 466 |
+
|
| 467 |
+
# TODO: replace the frame hack if a blessed way to know the calling
|
| 468 |
+
# module is ever developed
|
| 469 |
+
if module is None:
|
| 470 |
+
try:
|
| 471 |
+
module = sys._getframe(2).f_globals['__name__']
|
| 472 |
+
except (AttributeError, ValueError, KeyError) as exc:
|
| 473 |
+
pass
|
| 474 |
+
if module is None:
|
| 475 |
+
_make_class_unpicklable(enum_class)
|
| 476 |
+
else:
|
| 477 |
+
enum_class.__module__ = module
|
| 478 |
+
if qualname is not None:
|
| 479 |
+
enum_class.__qualname__ = qualname
|
| 480 |
+
|
| 481 |
+
return enum_class
|
| 482 |
+
|
| 483 |
+
def _convert_(cls, name, module, filter, source=None):
|
| 484 |
+
"""
|
| 485 |
+
Create a new Enum subclass that replaces a collection of global constants
|
| 486 |
+
"""
|
| 487 |
+
# convert all constants from source (or module) that pass filter() to
|
| 488 |
+
# a new Enum called name, and export the enum and its members back to
|
| 489 |
+
# module;
|
| 490 |
+
# also, replace the __reduce_ex__ method so unpickling works in
|
| 491 |
+
# previous Python versions
|
| 492 |
+
module_globals = vars(sys.modules[module])
|
| 493 |
+
if source:
|
| 494 |
+
source = vars(source)
|
| 495 |
+
else:
|
| 496 |
+
source = module_globals
|
| 497 |
+
# _value2member_map_ is populated in the same order every time
|
| 498 |
+
# for a consistent reverse mapping of number to name when there
|
| 499 |
+
# are multiple names for the same number.
|
| 500 |
+
members = [
|
| 501 |
+
(name, value)
|
| 502 |
+
for name, value in source.items()
|
| 503 |
+
if filter(name)]
|
| 504 |
+
try:
|
| 505 |
+
# sort by value
|
| 506 |
+
members.sort(key=lambda t: (t[1], t[0]))
|
| 507 |
+
except TypeError:
|
| 508 |
+
# unless some values aren't comparable, in which case sort by name
|
| 509 |
+
members.sort(key=lambda t: t[0])
|
| 510 |
+
cls = cls(name, members, module=module)
|
| 511 |
+
cls.__reduce_ex__ = _reduce_ex_by_name
|
| 512 |
+
module_globals.update(cls.__members__)
|
| 513 |
+
module_globals[name] = cls
|
| 514 |
+
return cls
|
| 515 |
+
|
| 516 |
+
def _convert(cls, *args, **kwargs):
|
| 517 |
+
import warnings
|
| 518 |
+
warnings.warn("_convert is deprecated and will be removed in 3.9, use "
|
| 519 |
+
"_convert_ instead.", DeprecationWarning, stacklevel=2)
|
| 520 |
+
return cls._convert_(*args, **kwargs)
|
| 521 |
+
|
| 522 |
+
@staticmethod
|
| 523 |
+
def _check_for_existing_members(class_name, bases):
|
| 524 |
+
for chain in bases:
|
| 525 |
+
for base in chain.__mro__:
|
| 526 |
+
if issubclass(base, Enum) and base._member_names_:
|
| 527 |
+
raise TypeError(
|
| 528 |
+
"%s: cannot extend enumeration %r"
|
| 529 |
+
% (class_name, base.__name__)
|
| 530 |
+
)
|
| 531 |
+
|
| 532 |
+
@staticmethod
|
| 533 |
+
def _get_mixins_(class_name, bases):
|
| 534 |
+
"""
|
| 535 |
+
Returns the type for creating enum members, and the first inherited
|
| 536 |
+
enum class.
|
| 537 |
+
|
| 538 |
+
bases: the tuple of bases that was given to __new__
|
| 539 |
+
"""
|
| 540 |
+
if not bases:
|
| 541 |
+
return object, Enum
|
| 542 |
+
|
| 543 |
+
def _find_data_type(bases):
|
| 544 |
+
data_types = []
|
| 545 |
+
for chain in bases:
|
| 546 |
+
candidate = None
|
| 547 |
+
for base in chain.__mro__:
|
| 548 |
+
if base is object:
|
| 549 |
+
continue
|
| 550 |
+
elif issubclass(base, Enum):
|
| 551 |
+
if base._member_type_ is not object:
|
| 552 |
+
data_types.append(base._member_type_)
|
| 553 |
+
break
|
| 554 |
+
elif '__new__' in base.__dict__:
|
| 555 |
+
if issubclass(base, Enum):
|
| 556 |
+
continue
|
| 557 |
+
data_types.append(candidate or base)
|
| 558 |
+
break
|
| 559 |
+
else:
|
| 560 |
+
candidate = base
|
| 561 |
+
if len(data_types) > 1:
|
| 562 |
+
raise TypeError('%r: too many data types: %r' % (class_name, data_types))
|
| 563 |
+
elif data_types:
|
| 564 |
+
return data_types[0]
|
| 565 |
+
else:
|
| 566 |
+
return None
|
| 567 |
+
|
| 568 |
+
# ensure final parent class is an Enum derivative, find any concrete
|
| 569 |
+
# data type, and check that Enum has no members
|
| 570 |
+
first_enum = bases[-1]
|
| 571 |
+
if not issubclass(first_enum, Enum):
|
| 572 |
+
raise TypeError("new enumerations should be created as "
|
| 573 |
+
"`EnumName([mixin_type, ...] [data_type,] enum_type)`")
|
| 574 |
+
member_type = _find_data_type(bases) or object
|
| 575 |
+
if first_enum._member_names_:
|
| 576 |
+
raise TypeError("Cannot extend enumerations")
|
| 577 |
+
return member_type, first_enum
|
| 578 |
+
|
| 579 |
+
@staticmethod
|
| 580 |
+
def _find_new_(classdict, member_type, first_enum):
|
| 581 |
+
"""
|
| 582 |
+
Returns the __new__ to be used for creating the enum members.
|
| 583 |
+
|
| 584 |
+
classdict: the class dictionary given to __new__
|
| 585 |
+
member_type: the data type whose __new__ will be used by default
|
| 586 |
+
first_enum: enumeration to check for an overriding __new__
|
| 587 |
+
"""
|
| 588 |
+
# now find the correct __new__, checking to see of one was defined
|
| 589 |
+
# by the user; also check earlier enum classes in case a __new__ was
|
| 590 |
+
# saved as __new_member__
|
| 591 |
+
__new__ = classdict.get('__new__', None)
|
| 592 |
+
|
| 593 |
+
# should __new__ be saved as __new_member__ later?
|
| 594 |
+
save_new = __new__ is not None
|
| 595 |
+
|
| 596 |
+
if __new__ is None:
|
| 597 |
+
# check all possibles for __new_member__ before falling back to
|
| 598 |
+
# __new__
|
| 599 |
+
for method in ('__new_member__', '__new__'):
|
| 600 |
+
for possible in (member_type, first_enum):
|
| 601 |
+
target = getattr(possible, method, None)
|
| 602 |
+
if target not in {
|
| 603 |
+
None,
|
| 604 |
+
None.__new__,
|
| 605 |
+
object.__new__,
|
| 606 |
+
Enum.__new__,
|
| 607 |
+
}:
|
| 608 |
+
__new__ = target
|
| 609 |
+
break
|
| 610 |
+
if __new__ is not None:
|
| 611 |
+
break
|
| 612 |
+
else:
|
| 613 |
+
__new__ = object.__new__
|
| 614 |
+
|
| 615 |
+
# if a non-object.__new__ is used then whatever value/tuple was
|
| 616 |
+
# assigned to the enum member name will be passed to __new__ and to the
|
| 617 |
+
# new enum member's __init__
|
| 618 |
+
if __new__ is object.__new__:
|
| 619 |
+
use_args = False
|
| 620 |
+
else:
|
| 621 |
+
use_args = True
|
| 622 |
+
return __new__, save_new, use_args
|
| 623 |
+
|
| 624 |
+
|
| 625 |
+
class Enum(metaclass=EnumMeta):
|
| 626 |
+
"""
|
| 627 |
+
Generic enumeration.
|
| 628 |
+
|
| 629 |
+
Derive from this class to define new enumerations.
|
| 630 |
+
"""
|
| 631 |
+
def __new__(cls, value):
|
| 632 |
+
# all enum instances are actually created during class construction
|
| 633 |
+
# without calling this method; this method is called by the metaclass'
|
| 634 |
+
# __call__ (i.e. Color(3) ), and by pickle
|
| 635 |
+
if type(value) is cls:
|
| 636 |
+
# For lookups like Color(Color.RED)
|
| 637 |
+
return value
|
| 638 |
+
# by-value search for a matching enum member
|
| 639 |
+
# see if it's in the reverse mapping (for hashable values)
|
| 640 |
+
try:
|
| 641 |
+
return cls._value2member_map_[value]
|
| 642 |
+
except KeyError:
|
| 643 |
+
# Not found, no need to do long O(n) search
|
| 644 |
+
pass
|
| 645 |
+
except TypeError:
|
| 646 |
+
# not there, now do long search -- O(n) behavior
|
| 647 |
+
for member in cls._member_map_.values():
|
| 648 |
+
if member._value_ == value:
|
| 649 |
+
return member
|
| 650 |
+
# still not found -- try _missing_ hook
|
| 651 |
+
try:
|
| 652 |
+
exc = None
|
| 653 |
+
result = cls._missing_(value)
|
| 654 |
+
except Exception as e:
|
| 655 |
+
exc = e
|
| 656 |
+
result = None
|
| 657 |
+
try:
|
| 658 |
+
if isinstance(result, cls):
|
| 659 |
+
return result
|
| 660 |
+
else:
|
| 661 |
+
ve_exc = ValueError("%r is not a valid %s" % (value, cls.__name__))
|
| 662 |
+
if result is None and exc is None:
|
| 663 |
+
raise ve_exc
|
| 664 |
+
elif exc is None:
|
| 665 |
+
exc = TypeError(
|
| 666 |
+
'error in %s._missing_: returned %r instead of None or a valid member'
|
| 667 |
+
% (cls.__name__, result)
|
| 668 |
+
)
|
| 669 |
+
exc.__context__ = ve_exc
|
| 670 |
+
raise exc
|
| 671 |
+
finally:
|
| 672 |
+
# ensure all variables that could hold an exception are destroyed
|
| 673 |
+
exc = None
|
| 674 |
+
ve_exc = None
|
| 675 |
+
|
| 676 |
+
def _generate_next_value_(name, start, count, last_values):
|
| 677 |
+
"""
|
| 678 |
+
Generate the next value when not given.
|
| 679 |
+
|
| 680 |
+
name: the name of the member
|
| 681 |
+
start: the initial start value or None
|
| 682 |
+
count: the number of existing members
|
| 683 |
+
last_value: the last value assigned or None
|
| 684 |
+
"""
|
| 685 |
+
for last_value in reversed(last_values):
|
| 686 |
+
try:
|
| 687 |
+
return last_value + 1
|
| 688 |
+
except TypeError:
|
| 689 |
+
pass
|
| 690 |
+
else:
|
| 691 |
+
return start
|
| 692 |
+
|
| 693 |
+
@classmethod
|
| 694 |
+
def _missing_(cls, value):
|
| 695 |
+
return None
|
| 696 |
+
|
| 697 |
+
def __repr__(self):
|
| 698 |
+
return "<%s.%s: %r>" % (
|
| 699 |
+
self.__class__.__name__, self._name_, self._value_)
|
| 700 |
+
|
| 701 |
+
def __str__(self):
|
| 702 |
+
return "%s.%s" % (self.__class__.__name__, self._name_)
|
| 703 |
+
|
| 704 |
+
def __dir__(self):
|
| 705 |
+
"""
|
| 706 |
+
Returns all members and all public methods
|
| 707 |
+
"""
|
| 708 |
+
added_behavior = [
|
| 709 |
+
m
|
| 710 |
+
for cls in self.__class__.mro()
|
| 711 |
+
for m in cls.__dict__
|
| 712 |
+
if m[0] != '_' and m not in self._member_map_
|
| 713 |
+
] + [m for m in self.__dict__ if m[0] != '_']
|
| 714 |
+
return (['__class__', '__doc__', '__module__'] + added_behavior)
|
| 715 |
+
|
| 716 |
+
def __format__(self, format_spec):
|
| 717 |
+
"""
|
| 718 |
+
Returns format using actual value type unless __str__ has been overridden.
|
| 719 |
+
"""
|
| 720 |
+
# mixed-in Enums should use the mixed-in type's __format__, otherwise
|
| 721 |
+
# we can get strange results with the Enum name showing up instead of
|
| 722 |
+
# the value
|
| 723 |
+
|
| 724 |
+
# pure Enum branch, or branch with __str__ explicitly overridden
|
| 725 |
+
str_overridden = type(self).__str__ not in (Enum.__str__, Flag.__str__)
|
| 726 |
+
if self._member_type_ is object or str_overridden:
|
| 727 |
+
cls = str
|
| 728 |
+
val = str(self)
|
| 729 |
+
# mix-in branch
|
| 730 |
+
else:
|
| 731 |
+
cls = self._member_type_
|
| 732 |
+
val = self._value_
|
| 733 |
+
return cls.__format__(val, format_spec)
|
| 734 |
+
|
| 735 |
+
def __hash__(self):
|
| 736 |
+
return hash(self._name_)
|
| 737 |
+
|
| 738 |
+
def __reduce_ex__(self, proto):
|
| 739 |
+
return self.__class__, (self._value_, )
|
| 740 |
+
|
| 741 |
+
# DynamicClassAttribute is used to provide access to the `name` and
|
| 742 |
+
# `value` properties of enum members while keeping some measure of
|
| 743 |
+
# protection from modification, while still allowing for an enumeration
|
| 744 |
+
# to have members named `name` and `value`. This works because enumeration
|
| 745 |
+
# members are not set directly on the enum class -- __getattr__ is
|
| 746 |
+
# used to look them up.
|
| 747 |
+
|
| 748 |
+
@DynamicClassAttribute
|
| 749 |
+
def name(self):
|
| 750 |
+
"""The name of the Enum member."""
|
| 751 |
+
return self._name_
|
| 752 |
+
|
| 753 |
+
@DynamicClassAttribute
|
| 754 |
+
def value(self):
|
| 755 |
+
"""The value of the Enum member."""
|
| 756 |
+
return self._value_
|
| 757 |
+
|
| 758 |
+
|
| 759 |
+
class IntEnum(int, Enum):
|
| 760 |
+
"""Enum where members are also (and must be) ints"""
|
| 761 |
+
|
| 762 |
+
|
| 763 |
+
def _reduce_ex_by_name(self, proto):
|
| 764 |
+
return self.name
|
| 765 |
+
|
| 766 |
+
class Flag(Enum):
|
| 767 |
+
"""
|
| 768 |
+
Support for flags
|
| 769 |
+
"""
|
| 770 |
+
|
| 771 |
+
def _generate_next_value_(name, start, count, last_values):
|
| 772 |
+
"""
|
| 773 |
+
Generate the next value when not given.
|
| 774 |
+
|
| 775 |
+
name: the name of the member
|
| 776 |
+
start: the initial start value or None
|
| 777 |
+
count: the number of existing members
|
| 778 |
+
last_value: the last value assigned or None
|
| 779 |
+
"""
|
| 780 |
+
if not count:
|
| 781 |
+
return start if start is not None else 1
|
| 782 |
+
for last_value in reversed(last_values):
|
| 783 |
+
try:
|
| 784 |
+
high_bit = _high_bit(last_value)
|
| 785 |
+
break
|
| 786 |
+
except Exception:
|
| 787 |
+
raise TypeError('Invalid Flag value: %r' % last_value) from None
|
| 788 |
+
return 2 ** (high_bit+1)
|
| 789 |
+
|
| 790 |
+
@classmethod
|
| 791 |
+
def _missing_(cls, value):
|
| 792 |
+
"""
|
| 793 |
+
Returns member (possibly creating it) if one can be found for value.
|
| 794 |
+
"""
|
| 795 |
+
original_value = value
|
| 796 |
+
if value < 0:
|
| 797 |
+
value = ~value
|
| 798 |
+
possible_member = cls._create_pseudo_member_(value)
|
| 799 |
+
if original_value < 0:
|
| 800 |
+
possible_member = ~possible_member
|
| 801 |
+
return possible_member
|
| 802 |
+
|
| 803 |
+
@classmethod
|
| 804 |
+
def _create_pseudo_member_(cls, value):
|
| 805 |
+
"""
|
| 806 |
+
Create a composite member iff value contains only members.
|
| 807 |
+
"""
|
| 808 |
+
pseudo_member = cls._value2member_map_.get(value, None)
|
| 809 |
+
if pseudo_member is None:
|
| 810 |
+
# verify all bits are accounted for
|
| 811 |
+
_, extra_flags = _decompose(cls, value)
|
| 812 |
+
if extra_flags:
|
| 813 |
+
raise ValueError("%r is not a valid %s" % (value, cls.__name__))
|
| 814 |
+
# construct a singleton enum pseudo-member
|
| 815 |
+
pseudo_member = object.__new__(cls)
|
| 816 |
+
pseudo_member._name_ = None
|
| 817 |
+
pseudo_member._value_ = value
|
| 818 |
+
# use setdefault in case another thread already created a composite
|
| 819 |
+
# with this value
|
| 820 |
+
pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member)
|
| 821 |
+
return pseudo_member
|
| 822 |
+
|
| 823 |
+
def __contains__(self, other):
|
| 824 |
+
"""
|
| 825 |
+
Returns True if self has at least the same flags set as other.
|
| 826 |
+
"""
|
| 827 |
+
if not isinstance(other, self.__class__):
|
| 828 |
+
raise TypeError(
|
| 829 |
+
"unsupported operand type(s) for 'in': '%s' and '%s'" % (
|
| 830 |
+
type(other).__qualname__, self.__class__.__qualname__))
|
| 831 |
+
return other._value_ & self._value_ == other._value_
|
| 832 |
+
|
| 833 |
+
def __repr__(self):
|
| 834 |
+
cls = self.__class__
|
| 835 |
+
if self._name_ is not None:
|
| 836 |
+
return '<%s.%s: %r>' % (cls.__name__, self._name_, self._value_)
|
| 837 |
+
members, uncovered = _decompose(cls, self._value_)
|
| 838 |
+
return '<%s.%s: %r>' % (
|
| 839 |
+
cls.__name__,
|
| 840 |
+
'|'.join([str(m._name_ or m._value_) for m in members]),
|
| 841 |
+
self._value_,
|
| 842 |
+
)
|
| 843 |
+
|
| 844 |
+
def __str__(self):
|
| 845 |
+
cls = self.__class__
|
| 846 |
+
if self._name_ is not None:
|
| 847 |
+
return '%s.%s' % (cls.__name__, self._name_)
|
| 848 |
+
members, uncovered = _decompose(cls, self._value_)
|
| 849 |
+
if len(members) == 1 and members[0]._name_ is None:
|
| 850 |
+
return '%s.%r' % (cls.__name__, members[0]._value_)
|
| 851 |
+
else:
|
| 852 |
+
return '%s.%s' % (
|
| 853 |
+
cls.__name__,
|
| 854 |
+
'|'.join([str(m._name_ or m._value_) for m in members]),
|
| 855 |
+
)
|
| 856 |
+
|
| 857 |
+
def __bool__(self):
|
| 858 |
+
return bool(self._value_)
|
| 859 |
+
|
| 860 |
+
def __or__(self, other):
|
| 861 |
+
if not isinstance(other, self.__class__):
|
| 862 |
+
return NotImplemented
|
| 863 |
+
return self.__class__(self._value_ | other._value_)
|
| 864 |
+
|
| 865 |
+
def __and__(self, other):
|
| 866 |
+
if not isinstance(other, self.__class__):
|
| 867 |
+
return NotImplemented
|
| 868 |
+
return self.__class__(self._value_ & other._value_)
|
| 869 |
+
|
| 870 |
+
def __xor__(self, other):
|
| 871 |
+
if not isinstance(other, self.__class__):
|
| 872 |
+
return NotImplemented
|
| 873 |
+
return self.__class__(self._value_ ^ other._value_)
|
| 874 |
+
|
| 875 |
+
def __invert__(self):
|
| 876 |
+
members, uncovered = _decompose(self.__class__, self._value_)
|
| 877 |
+
inverted = self.__class__(0)
|
| 878 |
+
for m in self.__class__:
|
| 879 |
+
if m not in members and not (m._value_ & self._value_):
|
| 880 |
+
inverted = inverted | m
|
| 881 |
+
return self.__class__(inverted)
|
| 882 |
+
|
| 883 |
+
|
| 884 |
+
class IntFlag(int, Flag):
|
| 885 |
+
"""
|
| 886 |
+
Support for integer-based Flags
|
| 887 |
+
"""
|
| 888 |
+
|
| 889 |
+
@classmethod
|
| 890 |
+
def _missing_(cls, value):
|
| 891 |
+
"""
|
| 892 |
+
Returns member (possibly creating it) if one can be found for value.
|
| 893 |
+
"""
|
| 894 |
+
if not isinstance(value, int):
|
| 895 |
+
raise ValueError("%r is not a valid %s" % (value, cls.__name__))
|
| 896 |
+
new_member = cls._create_pseudo_member_(value)
|
| 897 |
+
return new_member
|
| 898 |
+
|
| 899 |
+
@classmethod
|
| 900 |
+
def _create_pseudo_member_(cls, value):
|
| 901 |
+
"""
|
| 902 |
+
Create a composite member iff value contains only members.
|
| 903 |
+
"""
|
| 904 |
+
pseudo_member = cls._value2member_map_.get(value, None)
|
| 905 |
+
if pseudo_member is None:
|
| 906 |
+
need_to_create = [value]
|
| 907 |
+
# get unaccounted for bits
|
| 908 |
+
_, extra_flags = _decompose(cls, value)
|
| 909 |
+
# timer = 10
|
| 910 |
+
while extra_flags:
|
| 911 |
+
# timer -= 1
|
| 912 |
+
bit = _high_bit(extra_flags)
|
| 913 |
+
flag_value = 2 ** bit
|
| 914 |
+
if (flag_value not in cls._value2member_map_ and
|
| 915 |
+
flag_value not in need_to_create
|
| 916 |
+
):
|
| 917 |
+
need_to_create.append(flag_value)
|
| 918 |
+
if extra_flags == -flag_value:
|
| 919 |
+
extra_flags = 0
|
| 920 |
+
else:
|
| 921 |
+
extra_flags ^= flag_value
|
| 922 |
+
for value in reversed(need_to_create):
|
| 923 |
+
# construct singleton pseudo-members
|
| 924 |
+
pseudo_member = int.__new__(cls, value)
|
| 925 |
+
pseudo_member._name_ = None
|
| 926 |
+
pseudo_member._value_ = value
|
| 927 |
+
# use setdefault in case another thread already created a composite
|
| 928 |
+
# with this value
|
| 929 |
+
pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member)
|
| 930 |
+
return pseudo_member
|
| 931 |
+
|
| 932 |
+
def __or__(self, other):
|
| 933 |
+
if not isinstance(other, (self.__class__, int)):
|
| 934 |
+
return NotImplemented
|
| 935 |
+
result = self.__class__(self._value_ | self.__class__(other)._value_)
|
| 936 |
+
return result
|
| 937 |
+
|
| 938 |
+
def __and__(self, other):
|
| 939 |
+
if not isinstance(other, (self.__class__, int)):
|
| 940 |
+
return NotImplemented
|
| 941 |
+
return self.__class__(self._value_ & self.__class__(other)._value_)
|
| 942 |
+
|
| 943 |
+
def __xor__(self, other):
|
| 944 |
+
if not isinstance(other, (self.__class__, int)):
|
| 945 |
+
return NotImplemented
|
| 946 |
+
return self.__class__(self._value_ ^ self.__class__(other)._value_)
|
| 947 |
+
|
| 948 |
+
__ror__ = __or__
|
| 949 |
+
__rand__ = __and__
|
| 950 |
+
__rxor__ = __xor__
|
| 951 |
+
|
| 952 |
+
def __invert__(self):
|
| 953 |
+
result = self.__class__(~self._value_)
|
| 954 |
+
return result
|
| 955 |
+
|
| 956 |
+
|
| 957 |
+
def _high_bit(value):
|
| 958 |
+
"""
|
| 959 |
+
returns index of highest bit, or -1 if value is zero or negative
|
| 960 |
+
"""
|
| 961 |
+
return value.bit_length() - 1
|
| 962 |
+
|
| 963 |
+
def unique(enumeration):
|
| 964 |
+
"""
|
| 965 |
+
Class decorator for enumerations ensuring unique member values.
|
| 966 |
+
"""
|
| 967 |
+
duplicates = []
|
| 968 |
+
for name, member in enumeration.__members__.items():
|
| 969 |
+
if name != member.name:
|
| 970 |
+
duplicates.append((name, member.name))
|
| 971 |
+
if duplicates:
|
| 972 |
+
alias_details = ', '.join(
|
| 973 |
+
["%s -> %s" % (alias, name) for (alias, name) in duplicates])
|
| 974 |
+
raise ValueError('duplicate values found in %r: %s' %
|
| 975 |
+
(enumeration, alias_details))
|
| 976 |
+
return enumeration
|
| 977 |
+
|
| 978 |
+
def _decompose(flag, value):
|
| 979 |
+
"""
|
| 980 |
+
Extract all members from the value.
|
| 981 |
+
"""
|
| 982 |
+
# _decompose is only called if the value is not named
|
| 983 |
+
not_covered = value
|
| 984 |
+
negative = value < 0
|
| 985 |
+
# issue29167: wrap accesses to _value2member_map_ in a list to avoid race
|
| 986 |
+
# conditions between iterating over it and having more pseudo-
|
| 987 |
+
# members added to it
|
| 988 |
+
if negative:
|
| 989 |
+
# only check for named flags
|
| 990 |
+
flags_to_check = [
|
| 991 |
+
(m, v)
|
| 992 |
+
for v, m in list(flag._value2member_map_.items())
|
| 993 |
+
if m.name is not None
|
| 994 |
+
]
|
| 995 |
+
else:
|
| 996 |
+
# check for named flags and powers-of-two flags
|
| 997 |
+
flags_to_check = [
|
| 998 |
+
(m, v)
|
| 999 |
+
for v, m in list(flag._value2member_map_.items())
|
| 1000 |
+
if m.name is not None or _power_of_two(v)
|
| 1001 |
+
]
|
| 1002 |
+
members = []
|
| 1003 |
+
for member, member_value in flags_to_check:
|
| 1004 |
+
if member_value and member_value & value == member_value:
|
| 1005 |
+
members.append(member)
|
| 1006 |
+
not_covered &= ~member_value
|
| 1007 |
+
if not members and value in flag._value2member_map_:
|
| 1008 |
+
members.append(flag._value2member_map_[value])
|
| 1009 |
+
members.sort(key=lambda m: m._value_, reverse=True)
|
| 1010 |
+
if len(members) > 1 and members[0].value == value:
|
| 1011 |
+
# we have the breakdown, don't need the value member itself
|
| 1012 |
+
members.pop(0)
|
| 1013 |
+
return members, not_covered
|
| 1014 |
+
|
| 1015 |
+
def _power_of_two(value):
|
| 1016 |
+
if value < 1:
|
| 1017 |
+
return False
|
| 1018 |
+
return value == 2 ** _high_bit(value)
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/filecmp.py
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Utilities for comparing files and directories.
|
| 2 |
+
|
| 3 |
+
Classes:
|
| 4 |
+
dircmp
|
| 5 |
+
|
| 6 |
+
Functions:
|
| 7 |
+
cmp(f1, f2, shallow=True) -> int
|
| 8 |
+
cmpfiles(a, b, common) -> ([], [], [])
|
| 9 |
+
clear_cache()
|
| 10 |
+
|
| 11 |
+
"""
|
| 12 |
+
|
| 13 |
+
import os
|
| 14 |
+
import stat
|
| 15 |
+
from itertools import filterfalse
|
| 16 |
+
|
| 17 |
+
__all__ = ['clear_cache', 'cmp', 'dircmp', 'cmpfiles', 'DEFAULT_IGNORES']
|
| 18 |
+
|
| 19 |
+
_cache = {}
|
| 20 |
+
BUFSIZE = 8*1024
|
| 21 |
+
|
| 22 |
+
DEFAULT_IGNORES = [
|
| 23 |
+
'RCS', 'CVS', 'tags', '.git', '.hg', '.bzr', '_darcs', '__pycache__']
|
| 24 |
+
|
| 25 |
+
def clear_cache():
|
| 26 |
+
"""Clear the filecmp cache."""
|
| 27 |
+
_cache.clear()
|
| 28 |
+
|
| 29 |
+
def cmp(f1, f2, shallow=True):
|
| 30 |
+
"""Compare two files.
|
| 31 |
+
|
| 32 |
+
Arguments:
|
| 33 |
+
|
| 34 |
+
f1 -- First file name
|
| 35 |
+
|
| 36 |
+
f2 -- Second file name
|
| 37 |
+
|
| 38 |
+
shallow -- Just check stat signature (do not read the files).
|
| 39 |
+
defaults to True.
|
| 40 |
+
|
| 41 |
+
Return value:
|
| 42 |
+
|
| 43 |
+
True if the files are the same, False otherwise.
|
| 44 |
+
|
| 45 |
+
This function uses a cache for past comparisons and the results,
|
| 46 |
+
with cache entries invalidated if their stat information
|
| 47 |
+
changes. The cache may be cleared by calling clear_cache().
|
| 48 |
+
|
| 49 |
+
"""
|
| 50 |
+
|
| 51 |
+
s1 = _sig(os.stat(f1))
|
| 52 |
+
s2 = _sig(os.stat(f2))
|
| 53 |
+
if s1[0] != stat.S_IFREG or s2[0] != stat.S_IFREG:
|
| 54 |
+
return False
|
| 55 |
+
if shallow and s1 == s2:
|
| 56 |
+
return True
|
| 57 |
+
if s1[1] != s2[1]:
|
| 58 |
+
return False
|
| 59 |
+
|
| 60 |
+
outcome = _cache.get((f1, f2, s1, s2))
|
| 61 |
+
if outcome is None:
|
| 62 |
+
outcome = _do_cmp(f1, f2)
|
| 63 |
+
if len(_cache) > 100: # limit the maximum size of the cache
|
| 64 |
+
clear_cache()
|
| 65 |
+
_cache[f1, f2, s1, s2] = outcome
|
| 66 |
+
return outcome
|
| 67 |
+
|
| 68 |
+
def _sig(st):
|
| 69 |
+
return (stat.S_IFMT(st.st_mode),
|
| 70 |
+
st.st_size,
|
| 71 |
+
st.st_mtime)
|
| 72 |
+
|
| 73 |
+
def _do_cmp(f1, f2):
|
| 74 |
+
bufsize = BUFSIZE
|
| 75 |
+
with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2:
|
| 76 |
+
while True:
|
| 77 |
+
b1 = fp1.read(bufsize)
|
| 78 |
+
b2 = fp2.read(bufsize)
|
| 79 |
+
if b1 != b2:
|
| 80 |
+
return False
|
| 81 |
+
if not b1:
|
| 82 |
+
return True
|
| 83 |
+
|
| 84 |
+
# Directory comparison class.
|
| 85 |
+
#
|
| 86 |
+
class dircmp:
|
| 87 |
+
"""A class that manages the comparison of 2 directories.
|
| 88 |
+
|
| 89 |
+
dircmp(a, b, ignore=None, hide=None)
|
| 90 |
+
A and B are directories.
|
| 91 |
+
IGNORE is a list of names to ignore,
|
| 92 |
+
defaults to DEFAULT_IGNORES.
|
| 93 |
+
HIDE is a list of names to hide,
|
| 94 |
+
defaults to [os.curdir, os.pardir].
|
| 95 |
+
|
| 96 |
+
High level usage:
|
| 97 |
+
x = dircmp(dir1, dir2)
|
| 98 |
+
x.report() -> prints a report on the differences between dir1 and dir2
|
| 99 |
+
or
|
| 100 |
+
x.report_partial_closure() -> prints report on differences between dir1
|
| 101 |
+
and dir2, and reports on common immediate subdirectories.
|
| 102 |
+
x.report_full_closure() -> like report_partial_closure,
|
| 103 |
+
but fully recursive.
|
| 104 |
+
|
| 105 |
+
Attributes:
|
| 106 |
+
left_list, right_list: The files in dir1 and dir2,
|
| 107 |
+
filtered by hide and ignore.
|
| 108 |
+
common: a list of names in both dir1 and dir2.
|
| 109 |
+
left_only, right_only: names only in dir1, dir2.
|
| 110 |
+
common_dirs: subdirectories in both dir1 and dir2.
|
| 111 |
+
common_files: files in both dir1 and dir2.
|
| 112 |
+
common_funny: names in both dir1 and dir2 where the type differs between
|
| 113 |
+
dir1 and dir2, or the name is not stat-able.
|
| 114 |
+
same_files: list of identical files.
|
| 115 |
+
diff_files: list of filenames which differ.
|
| 116 |
+
funny_files: list of files which could not be compared.
|
| 117 |
+
subdirs: a dictionary of dircmp objects, keyed by names in common_dirs.
|
| 118 |
+
"""
|
| 119 |
+
|
| 120 |
+
def __init__(self, a, b, ignore=None, hide=None): # Initialize
|
| 121 |
+
self.left = a
|
| 122 |
+
self.right = b
|
| 123 |
+
if hide is None:
|
| 124 |
+
self.hide = [os.curdir, os.pardir] # Names never to be shown
|
| 125 |
+
else:
|
| 126 |
+
self.hide = hide
|
| 127 |
+
if ignore is None:
|
| 128 |
+
self.ignore = DEFAULT_IGNORES
|
| 129 |
+
else:
|
| 130 |
+
self.ignore = ignore
|
| 131 |
+
|
| 132 |
+
def phase0(self): # Compare everything except common subdirectories
|
| 133 |
+
self.left_list = _filter(os.listdir(self.left),
|
| 134 |
+
self.hide+self.ignore)
|
| 135 |
+
self.right_list = _filter(os.listdir(self.right),
|
| 136 |
+
self.hide+self.ignore)
|
| 137 |
+
self.left_list.sort()
|
| 138 |
+
self.right_list.sort()
|
| 139 |
+
|
| 140 |
+
def phase1(self): # Compute common names
|
| 141 |
+
a = dict(zip(map(os.path.normcase, self.left_list), self.left_list))
|
| 142 |
+
b = dict(zip(map(os.path.normcase, self.right_list), self.right_list))
|
| 143 |
+
self.common = list(map(a.__getitem__, filter(b.__contains__, a)))
|
| 144 |
+
self.left_only = list(map(a.__getitem__, filterfalse(b.__contains__, a)))
|
| 145 |
+
self.right_only = list(map(b.__getitem__, filterfalse(a.__contains__, b)))
|
| 146 |
+
|
| 147 |
+
def phase2(self): # Distinguish files, directories, funnies
|
| 148 |
+
self.common_dirs = []
|
| 149 |
+
self.common_files = []
|
| 150 |
+
self.common_funny = []
|
| 151 |
+
|
| 152 |
+
for x in self.common:
|
| 153 |
+
a_path = os.path.join(self.left, x)
|
| 154 |
+
b_path = os.path.join(self.right, x)
|
| 155 |
+
|
| 156 |
+
ok = 1
|
| 157 |
+
try:
|
| 158 |
+
a_stat = os.stat(a_path)
|
| 159 |
+
except OSError as why:
|
| 160 |
+
# print('Can\'t stat', a_path, ':', why.args[1])
|
| 161 |
+
ok = 0
|
| 162 |
+
try:
|
| 163 |
+
b_stat = os.stat(b_path)
|
| 164 |
+
except OSError as why:
|
| 165 |
+
# print('Can\'t stat', b_path, ':', why.args[1])
|
| 166 |
+
ok = 0
|
| 167 |
+
|
| 168 |
+
if ok:
|
| 169 |
+
a_type = stat.S_IFMT(a_stat.st_mode)
|
| 170 |
+
b_type = stat.S_IFMT(b_stat.st_mode)
|
| 171 |
+
if a_type != b_type:
|
| 172 |
+
self.common_funny.append(x)
|
| 173 |
+
elif stat.S_ISDIR(a_type):
|
| 174 |
+
self.common_dirs.append(x)
|
| 175 |
+
elif stat.S_ISREG(a_type):
|
| 176 |
+
self.common_files.append(x)
|
| 177 |
+
else:
|
| 178 |
+
self.common_funny.append(x)
|
| 179 |
+
else:
|
| 180 |
+
self.common_funny.append(x)
|
| 181 |
+
|
| 182 |
+
def phase3(self): # Find out differences between common files
|
| 183 |
+
xx = cmpfiles(self.left, self.right, self.common_files)
|
| 184 |
+
self.same_files, self.diff_files, self.funny_files = xx
|
| 185 |
+
|
| 186 |
+
def phase4(self): # Find out differences between common subdirectories
|
| 187 |
+
# A new dircmp object is created for each common subdirectory,
|
| 188 |
+
# these are stored in a dictionary indexed by filename.
|
| 189 |
+
# The hide and ignore properties are inherited from the parent
|
| 190 |
+
self.subdirs = {}
|
| 191 |
+
for x in self.common_dirs:
|
| 192 |
+
a_x = os.path.join(self.left, x)
|
| 193 |
+
b_x = os.path.join(self.right, x)
|
| 194 |
+
self.subdirs[x] = dircmp(a_x, b_x, self.ignore, self.hide)
|
| 195 |
+
|
| 196 |
+
def phase4_closure(self): # Recursively call phase4() on subdirectories
|
| 197 |
+
self.phase4()
|
| 198 |
+
for sd in self.subdirs.values():
|
| 199 |
+
sd.phase4_closure()
|
| 200 |
+
|
| 201 |
+
def report(self): # Print a report on the differences between a and b
|
| 202 |
+
# Output format is purposely lousy
|
| 203 |
+
print('diff', self.left, self.right)
|
| 204 |
+
if self.left_only:
|
| 205 |
+
self.left_only.sort()
|
| 206 |
+
print('Only in', self.left, ':', self.left_only)
|
| 207 |
+
if self.right_only:
|
| 208 |
+
self.right_only.sort()
|
| 209 |
+
print('Only in', self.right, ':', self.right_only)
|
| 210 |
+
if self.same_files:
|
| 211 |
+
self.same_files.sort()
|
| 212 |
+
print('Identical files :', self.same_files)
|
| 213 |
+
if self.diff_files:
|
| 214 |
+
self.diff_files.sort()
|
| 215 |
+
print('Differing files :', self.diff_files)
|
| 216 |
+
if self.funny_files:
|
| 217 |
+
self.funny_files.sort()
|
| 218 |
+
print('Trouble with common files :', self.funny_files)
|
| 219 |
+
if self.common_dirs:
|
| 220 |
+
self.common_dirs.sort()
|
| 221 |
+
print('Common subdirectories :', self.common_dirs)
|
| 222 |
+
if self.common_funny:
|
| 223 |
+
self.common_funny.sort()
|
| 224 |
+
print('Common funny cases :', self.common_funny)
|
| 225 |
+
|
| 226 |
+
def report_partial_closure(self): # Print reports on self and on subdirs
|
| 227 |
+
self.report()
|
| 228 |
+
for sd in self.subdirs.values():
|
| 229 |
+
print()
|
| 230 |
+
sd.report()
|
| 231 |
+
|
| 232 |
+
def report_full_closure(self): # Report on self and subdirs recursively
|
| 233 |
+
self.report()
|
| 234 |
+
for sd in self.subdirs.values():
|
| 235 |
+
print()
|
| 236 |
+
sd.report_full_closure()
|
| 237 |
+
|
| 238 |
+
methodmap = dict(subdirs=phase4,
|
| 239 |
+
same_files=phase3, diff_files=phase3, funny_files=phase3,
|
| 240 |
+
common_dirs = phase2, common_files=phase2, common_funny=phase2,
|
| 241 |
+
common=phase1, left_only=phase1, right_only=phase1,
|
| 242 |
+
left_list=phase0, right_list=phase0)
|
| 243 |
+
|
| 244 |
+
def __getattr__(self, attr):
|
| 245 |
+
if attr not in self.methodmap:
|
| 246 |
+
raise AttributeError(attr)
|
| 247 |
+
self.methodmap[attr](self)
|
| 248 |
+
return getattr(self, attr)
|
| 249 |
+
|
| 250 |
+
def cmpfiles(a, b, common, shallow=True):
|
| 251 |
+
"""Compare common files in two directories.
|
| 252 |
+
|
| 253 |
+
a, b -- directory names
|
| 254 |
+
common -- list of file names found in both directories
|
| 255 |
+
shallow -- if true, do comparison based solely on stat() information
|
| 256 |
+
|
| 257 |
+
Returns a tuple of three lists:
|
| 258 |
+
files that compare equal
|
| 259 |
+
files that are different
|
| 260 |
+
filenames that aren't regular files.
|
| 261 |
+
|
| 262 |
+
"""
|
| 263 |
+
res = ([], [], [])
|
| 264 |
+
for x in common:
|
| 265 |
+
ax = os.path.join(a, x)
|
| 266 |
+
bx = os.path.join(b, x)
|
| 267 |
+
res[_cmp(ax, bx, shallow)].append(x)
|
| 268 |
+
return res
|
| 269 |
+
|
| 270 |
+
|
| 271 |
+
# Compare two files.
|
| 272 |
+
# Return:
|
| 273 |
+
# 0 for equal
|
| 274 |
+
# 1 for different
|
| 275 |
+
# 2 for funny cases (can't stat, etc.)
|
| 276 |
+
#
|
| 277 |
+
def _cmp(a, b, sh, abs=abs, cmp=cmp):
|
| 278 |
+
try:
|
| 279 |
+
return not abs(cmp(a, b, sh))
|
| 280 |
+
except OSError:
|
| 281 |
+
return 2
|
| 282 |
+
|
| 283 |
+
|
| 284 |
+
# Return a copy with items that occur in skip removed.
|
| 285 |
+
#
|
| 286 |
+
def _filter(flist, skip):
|
| 287 |
+
return list(filterfalse(skip.__contains__, flist))
|
| 288 |
+
|
| 289 |
+
|
| 290 |
+
# Demonstration and testing.
|
| 291 |
+
#
|
| 292 |
+
def demo():
|
| 293 |
+
import sys
|
| 294 |
+
import getopt
|
| 295 |
+
options, args = getopt.getopt(sys.argv[1:], 'r')
|
| 296 |
+
if len(args) != 2:
|
| 297 |
+
raise getopt.GetoptError('need exactly two args', None)
|
| 298 |
+
dd = dircmp(args[0], args[1])
|
| 299 |
+
if ('-r', '') in options:
|
| 300 |
+
dd.report_full_closure()
|
| 301 |
+
else:
|
| 302 |
+
dd.report()
|
| 303 |
+
|
| 304 |
+
if __name__ == '__main__':
|
| 305 |
+
demo()
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/formatter.py
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Generic output formatting.
|
| 2 |
+
|
| 3 |
+
Formatter objects transform an abstract flow of formatting events into
|
| 4 |
+
specific output events on writer objects. Formatters manage several stack
|
| 5 |
+
structures to allow various properties of a writer object to be changed and
|
| 6 |
+
restored; writers need not be able to handle relative changes nor any sort
|
| 7 |
+
of ``change back'' operation. Specific writer properties which may be
|
| 8 |
+
controlled via formatter objects are horizontal alignment, font, and left
|
| 9 |
+
margin indentations. A mechanism is provided which supports providing
|
| 10 |
+
arbitrary, non-exclusive style settings to a writer as well. Additional
|
| 11 |
+
interfaces facilitate formatting events which are not reversible, such as
|
| 12 |
+
paragraph separation.
|
| 13 |
+
|
| 14 |
+
Writer objects encapsulate device interfaces. Abstract devices, such as
|
| 15 |
+
file formats, are supported as well as physical devices. The provided
|
| 16 |
+
implementations all work with abstract devices. The interface makes
|
| 17 |
+
available mechanisms for setting the properties which formatter objects
|
| 18 |
+
manage and inserting data into the output.
|
| 19 |
+
"""
|
| 20 |
+
|
| 21 |
+
import sys
|
| 22 |
+
import warnings
|
| 23 |
+
warnings.warn('the formatter module is deprecated', DeprecationWarning,
|
| 24 |
+
stacklevel=2)
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
AS_IS = None
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
class NullFormatter:
|
| 31 |
+
"""A formatter which does nothing.
|
| 32 |
+
|
| 33 |
+
If the writer parameter is omitted, a NullWriter instance is created.
|
| 34 |
+
No methods of the writer are called by NullFormatter instances.
|
| 35 |
+
|
| 36 |
+
Implementations should inherit from this class if implementing a writer
|
| 37 |
+
interface but don't need to inherit any implementation.
|
| 38 |
+
|
| 39 |
+
"""
|
| 40 |
+
|
| 41 |
+
def __init__(self, writer=None):
|
| 42 |
+
if writer is None:
|
| 43 |
+
writer = NullWriter()
|
| 44 |
+
self.writer = writer
|
| 45 |
+
def end_paragraph(self, blankline): pass
|
| 46 |
+
def add_line_break(self): pass
|
| 47 |
+
def add_hor_rule(self, *args, **kw): pass
|
| 48 |
+
def add_label_data(self, format, counter, blankline=None): pass
|
| 49 |
+
def add_flowing_data(self, data): pass
|
| 50 |
+
def add_literal_data(self, data): pass
|
| 51 |
+
def flush_softspace(self): pass
|
| 52 |
+
def push_alignment(self, align): pass
|
| 53 |
+
def pop_alignment(self): pass
|
| 54 |
+
def push_font(self, x): pass
|
| 55 |
+
def pop_font(self): pass
|
| 56 |
+
def push_margin(self, margin): pass
|
| 57 |
+
def pop_margin(self): pass
|
| 58 |
+
def set_spacing(self, spacing): pass
|
| 59 |
+
def push_style(self, *styles): pass
|
| 60 |
+
def pop_style(self, n=1): pass
|
| 61 |
+
def assert_line_data(self, flag=1): pass
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
class AbstractFormatter:
|
| 65 |
+
"""The standard formatter.
|
| 66 |
+
|
| 67 |
+
This implementation has demonstrated wide applicability to many writers,
|
| 68 |
+
and may be used directly in most circumstances. It has been used to
|
| 69 |
+
implement a full-featured World Wide Web browser.
|
| 70 |
+
|
| 71 |
+
"""
|
| 72 |
+
|
| 73 |
+
# Space handling policy: blank spaces at the boundary between elements
|
| 74 |
+
# are handled by the outermost context. "Literal" data is not checked
|
| 75 |
+
# to determine context, so spaces in literal data are handled directly
|
| 76 |
+
# in all circumstances.
|
| 77 |
+
|
| 78 |
+
def __init__(self, writer):
|
| 79 |
+
self.writer = writer # Output device
|
| 80 |
+
self.align = None # Current alignment
|
| 81 |
+
self.align_stack = [] # Alignment stack
|
| 82 |
+
self.font_stack = [] # Font state
|
| 83 |
+
self.margin_stack = [] # Margin state
|
| 84 |
+
self.spacing = None # Vertical spacing state
|
| 85 |
+
self.style_stack = [] # Other state, e.g. color
|
| 86 |
+
self.nospace = 1 # Should leading space be suppressed
|
| 87 |
+
self.softspace = 0 # Should a space be inserted
|
| 88 |
+
self.para_end = 1 # Just ended a paragraph
|
| 89 |
+
self.parskip = 0 # Skipped space between paragraphs?
|
| 90 |
+
self.hard_break = 1 # Have a hard break
|
| 91 |
+
self.have_label = 0
|
| 92 |
+
|
| 93 |
+
def end_paragraph(self, blankline):
|
| 94 |
+
if not self.hard_break:
|
| 95 |
+
self.writer.send_line_break()
|
| 96 |
+
self.have_label = 0
|
| 97 |
+
if self.parskip < blankline and not self.have_label:
|
| 98 |
+
self.writer.send_paragraph(blankline - self.parskip)
|
| 99 |
+
self.parskip = blankline
|
| 100 |
+
self.have_label = 0
|
| 101 |
+
self.hard_break = self.nospace = self.para_end = 1
|
| 102 |
+
self.softspace = 0
|
| 103 |
+
|
| 104 |
+
def add_line_break(self):
|
| 105 |
+
if not (self.hard_break or self.para_end):
|
| 106 |
+
self.writer.send_line_break()
|
| 107 |
+
self.have_label = self.parskip = 0
|
| 108 |
+
self.hard_break = self.nospace = 1
|
| 109 |
+
self.softspace = 0
|
| 110 |
+
|
| 111 |
+
def add_hor_rule(self, *args, **kw):
|
| 112 |
+
if not self.hard_break:
|
| 113 |
+
self.writer.send_line_break()
|
| 114 |
+
self.writer.send_hor_rule(*args, **kw)
|
| 115 |
+
self.hard_break = self.nospace = 1
|
| 116 |
+
self.have_label = self.para_end = self.softspace = self.parskip = 0
|
| 117 |
+
|
| 118 |
+
def add_label_data(self, format, counter, blankline = None):
|
| 119 |
+
if self.have_label or not self.hard_break:
|
| 120 |
+
self.writer.send_line_break()
|
| 121 |
+
if not self.para_end:
|
| 122 |
+
self.writer.send_paragraph((blankline and 1) or 0)
|
| 123 |
+
if isinstance(format, str):
|
| 124 |
+
self.writer.send_label_data(self.format_counter(format, counter))
|
| 125 |
+
else:
|
| 126 |
+
self.writer.send_label_data(format)
|
| 127 |
+
self.nospace = self.have_label = self.hard_break = self.para_end = 1
|
| 128 |
+
self.softspace = self.parskip = 0
|
| 129 |
+
|
| 130 |
+
def format_counter(self, format, counter):
|
| 131 |
+
label = ''
|
| 132 |
+
for c in format:
|
| 133 |
+
if c == '1':
|
| 134 |
+
label = label + ('%d' % counter)
|
| 135 |
+
elif c in 'aA':
|
| 136 |
+
if counter > 0:
|
| 137 |
+
label = label + self.format_letter(c, counter)
|
| 138 |
+
elif c in 'iI':
|
| 139 |
+
if counter > 0:
|
| 140 |
+
label = label + self.format_roman(c, counter)
|
| 141 |
+
else:
|
| 142 |
+
label = label + c
|
| 143 |
+
return label
|
| 144 |
+
|
| 145 |
+
def format_letter(self, case, counter):
|
| 146 |
+
label = ''
|
| 147 |
+
while counter > 0:
|
| 148 |
+
counter, x = divmod(counter-1, 26)
|
| 149 |
+
# This makes a strong assumption that lowercase letters
|
| 150 |
+
# and uppercase letters form two contiguous blocks, with
|
| 151 |
+
# letters in order!
|
| 152 |
+
s = chr(ord(case) + x)
|
| 153 |
+
label = s + label
|
| 154 |
+
return label
|
| 155 |
+
|
| 156 |
+
def format_roman(self, case, counter):
|
| 157 |
+
ones = ['i', 'x', 'c', 'm']
|
| 158 |
+
fives = ['v', 'l', 'd']
|
| 159 |
+
label, index = '', 0
|
| 160 |
+
# This will die of IndexError when counter is too big
|
| 161 |
+
while counter > 0:
|
| 162 |
+
counter, x = divmod(counter, 10)
|
| 163 |
+
if x == 9:
|
| 164 |
+
label = ones[index] + ones[index+1] + label
|
| 165 |
+
elif x == 4:
|
| 166 |
+
label = ones[index] + fives[index] + label
|
| 167 |
+
else:
|
| 168 |
+
if x >= 5:
|
| 169 |
+
s = fives[index]
|
| 170 |
+
x = x-5
|
| 171 |
+
else:
|
| 172 |
+
s = ''
|
| 173 |
+
s = s + ones[index]*x
|
| 174 |
+
label = s + label
|
| 175 |
+
index = index + 1
|
| 176 |
+
if case == 'I':
|
| 177 |
+
return label.upper()
|
| 178 |
+
return label
|
| 179 |
+
|
| 180 |
+
def add_flowing_data(self, data):
|
| 181 |
+
if not data: return
|
| 182 |
+
prespace = data[:1].isspace()
|
| 183 |
+
postspace = data[-1:].isspace()
|
| 184 |
+
data = " ".join(data.split())
|
| 185 |
+
if self.nospace and not data:
|
| 186 |
+
return
|
| 187 |
+
elif prespace or self.softspace:
|
| 188 |
+
if not data:
|
| 189 |
+
if not self.nospace:
|
| 190 |
+
self.softspace = 1
|
| 191 |
+
self.parskip = 0
|
| 192 |
+
return
|
| 193 |
+
if not self.nospace:
|
| 194 |
+
data = ' ' + data
|
| 195 |
+
self.hard_break = self.nospace = self.para_end = \
|
| 196 |
+
self.parskip = self.have_label = 0
|
| 197 |
+
self.softspace = postspace
|
| 198 |
+
self.writer.send_flowing_data(data)
|
| 199 |
+
|
| 200 |
+
def add_literal_data(self, data):
|
| 201 |
+
if not data: return
|
| 202 |
+
if self.softspace:
|
| 203 |
+
self.writer.send_flowing_data(" ")
|
| 204 |
+
self.hard_break = data[-1:] == '\n'
|
| 205 |
+
self.nospace = self.para_end = self.softspace = \
|
| 206 |
+
self.parskip = self.have_label = 0
|
| 207 |
+
self.writer.send_literal_data(data)
|
| 208 |
+
|
| 209 |
+
def flush_softspace(self):
|
| 210 |
+
if self.softspace:
|
| 211 |
+
self.hard_break = self.para_end = self.parskip = \
|
| 212 |
+
self.have_label = self.softspace = 0
|
| 213 |
+
self.nospace = 1
|
| 214 |
+
self.writer.send_flowing_data(' ')
|
| 215 |
+
|
| 216 |
+
def push_alignment(self, align):
|
| 217 |
+
if align and align != self.align:
|
| 218 |
+
self.writer.new_alignment(align)
|
| 219 |
+
self.align = align
|
| 220 |
+
self.align_stack.append(align)
|
| 221 |
+
else:
|
| 222 |
+
self.align_stack.append(self.align)
|
| 223 |
+
|
| 224 |
+
def pop_alignment(self):
|
| 225 |
+
if self.align_stack:
|
| 226 |
+
del self.align_stack[-1]
|
| 227 |
+
if self.align_stack:
|
| 228 |
+
self.align = align = self.align_stack[-1]
|
| 229 |
+
self.writer.new_alignment(align)
|
| 230 |
+
else:
|
| 231 |
+
self.align = None
|
| 232 |
+
self.writer.new_alignment(None)
|
| 233 |
+
|
| 234 |
+
def push_font(self, font):
|
| 235 |
+
size, i, b, tt = font
|
| 236 |
+
if self.softspace:
|
| 237 |
+
self.hard_break = self.para_end = self.softspace = 0
|
| 238 |
+
self.nospace = 1
|
| 239 |
+
self.writer.send_flowing_data(' ')
|
| 240 |
+
if self.font_stack:
|
| 241 |
+
csize, ci, cb, ctt = self.font_stack[-1]
|
| 242 |
+
if size is AS_IS: size = csize
|
| 243 |
+
if i is AS_IS: i = ci
|
| 244 |
+
if b is AS_IS: b = cb
|
| 245 |
+
if tt is AS_IS: tt = ctt
|
| 246 |
+
font = (size, i, b, tt)
|
| 247 |
+
self.font_stack.append(font)
|
| 248 |
+
self.writer.new_font(font)
|
| 249 |
+
|
| 250 |
+
def pop_font(self):
|
| 251 |
+
if self.font_stack:
|
| 252 |
+
del self.font_stack[-1]
|
| 253 |
+
if self.font_stack:
|
| 254 |
+
font = self.font_stack[-1]
|
| 255 |
+
else:
|
| 256 |
+
font = None
|
| 257 |
+
self.writer.new_font(font)
|
| 258 |
+
|
| 259 |
+
def push_margin(self, margin):
|
| 260 |
+
self.margin_stack.append(margin)
|
| 261 |
+
fstack = [m for m in self.margin_stack if m]
|
| 262 |
+
if not margin and fstack:
|
| 263 |
+
margin = fstack[-1]
|
| 264 |
+
self.writer.new_margin(margin, len(fstack))
|
| 265 |
+
|
| 266 |
+
def pop_margin(self):
|
| 267 |
+
if self.margin_stack:
|
| 268 |
+
del self.margin_stack[-1]
|
| 269 |
+
fstack = [m for m in self.margin_stack if m]
|
| 270 |
+
if fstack:
|
| 271 |
+
margin = fstack[-1]
|
| 272 |
+
else:
|
| 273 |
+
margin = None
|
| 274 |
+
self.writer.new_margin(margin, len(fstack))
|
| 275 |
+
|
| 276 |
+
def set_spacing(self, spacing):
|
| 277 |
+
self.spacing = spacing
|
| 278 |
+
self.writer.new_spacing(spacing)
|
| 279 |
+
|
| 280 |
+
def push_style(self, *styles):
|
| 281 |
+
if self.softspace:
|
| 282 |
+
self.hard_break = self.para_end = self.softspace = 0
|
| 283 |
+
self.nospace = 1
|
| 284 |
+
self.writer.send_flowing_data(' ')
|
| 285 |
+
for style in styles:
|
| 286 |
+
self.style_stack.append(style)
|
| 287 |
+
self.writer.new_styles(tuple(self.style_stack))
|
| 288 |
+
|
| 289 |
+
def pop_style(self, n=1):
|
| 290 |
+
del self.style_stack[-n:]
|
| 291 |
+
self.writer.new_styles(tuple(self.style_stack))
|
| 292 |
+
|
| 293 |
+
def assert_line_data(self, flag=1):
|
| 294 |
+
self.nospace = self.hard_break = not flag
|
| 295 |
+
self.para_end = self.parskip = self.have_label = 0
|
| 296 |
+
|
| 297 |
+
|
| 298 |
+
class NullWriter:
|
| 299 |
+
"""Minimal writer interface to use in testing & inheritance.
|
| 300 |
+
|
| 301 |
+
A writer which only provides the interface definition; no actions are
|
| 302 |
+
taken on any methods. This should be the base class for all writers
|
| 303 |
+
which do not need to inherit any implementation methods.
|
| 304 |
+
|
| 305 |
+
"""
|
| 306 |
+
def __init__(self): pass
|
| 307 |
+
def flush(self): pass
|
| 308 |
+
def new_alignment(self, align): pass
|
| 309 |
+
def new_font(self, font): pass
|
| 310 |
+
def new_margin(self, margin, level): pass
|
| 311 |
+
def new_spacing(self, spacing): pass
|
| 312 |
+
def new_styles(self, styles): pass
|
| 313 |
+
def send_paragraph(self, blankline): pass
|
| 314 |
+
def send_line_break(self): pass
|
| 315 |
+
def send_hor_rule(self, *args, **kw): pass
|
| 316 |
+
def send_label_data(self, data): pass
|
| 317 |
+
def send_flowing_data(self, data): pass
|
| 318 |
+
def send_literal_data(self, data): pass
|
| 319 |
+
|
| 320 |
+
|
| 321 |
+
class AbstractWriter(NullWriter):
|
| 322 |
+
"""A writer which can be used in debugging formatters, but not much else.
|
| 323 |
+
|
| 324 |
+
Each method simply announces itself by printing its name and
|
| 325 |
+
arguments on standard output.
|
| 326 |
+
|
| 327 |
+
"""
|
| 328 |
+
|
| 329 |
+
def new_alignment(self, align):
|
| 330 |
+
print("new_alignment(%r)" % (align,))
|
| 331 |
+
|
| 332 |
+
def new_font(self, font):
|
| 333 |
+
print("new_font(%r)" % (font,))
|
| 334 |
+
|
| 335 |
+
def new_margin(self, margin, level):
|
| 336 |
+
print("new_margin(%r, %d)" % (margin, level))
|
| 337 |
+
|
| 338 |
+
def new_spacing(self, spacing):
|
| 339 |
+
print("new_spacing(%r)" % (spacing,))
|
| 340 |
+
|
| 341 |
+
def new_styles(self, styles):
|
| 342 |
+
print("new_styles(%r)" % (styles,))
|
| 343 |
+
|
| 344 |
+
def send_paragraph(self, blankline):
|
| 345 |
+
print("send_paragraph(%r)" % (blankline,))
|
| 346 |
+
|
| 347 |
+
def send_line_break(self):
|
| 348 |
+
print("send_line_break()")
|
| 349 |
+
|
| 350 |
+
def send_hor_rule(self, *args, **kw):
|
| 351 |
+
print("send_hor_rule()")
|
| 352 |
+
|
| 353 |
+
def send_label_data(self, data):
|
| 354 |
+
print("send_label_data(%r)" % (data,))
|
| 355 |
+
|
| 356 |
+
def send_flowing_data(self, data):
|
| 357 |
+
print("send_flowing_data(%r)" % (data,))
|
| 358 |
+
|
| 359 |
+
def send_literal_data(self, data):
|
| 360 |
+
print("send_literal_data(%r)" % (data,))
|
| 361 |
+
|
| 362 |
+
|
| 363 |
+
class DumbWriter(NullWriter):
|
| 364 |
+
"""Simple writer class which writes output on the file object passed in
|
| 365 |
+
as the file parameter or, if file is omitted, on standard output. The
|
| 366 |
+
output is simply word-wrapped to the number of columns specified by
|
| 367 |
+
the maxcol parameter. This class is suitable for reflowing a sequence
|
| 368 |
+
of paragraphs.
|
| 369 |
+
|
| 370 |
+
"""
|
| 371 |
+
|
| 372 |
+
def __init__(self, file=None, maxcol=72):
|
| 373 |
+
self.file = file or sys.stdout
|
| 374 |
+
self.maxcol = maxcol
|
| 375 |
+
NullWriter.__init__(self)
|
| 376 |
+
self.reset()
|
| 377 |
+
|
| 378 |
+
def reset(self):
|
| 379 |
+
self.col = 0
|
| 380 |
+
self.atbreak = 0
|
| 381 |
+
|
| 382 |
+
def send_paragraph(self, blankline):
|
| 383 |
+
self.file.write('\n'*blankline)
|
| 384 |
+
self.col = 0
|
| 385 |
+
self.atbreak = 0
|
| 386 |
+
|
| 387 |
+
def send_line_break(self):
|
| 388 |
+
self.file.write('\n')
|
| 389 |
+
self.col = 0
|
| 390 |
+
self.atbreak = 0
|
| 391 |
+
|
| 392 |
+
def send_hor_rule(self, *args, **kw):
|
| 393 |
+
self.file.write('\n')
|
| 394 |
+
self.file.write('-'*self.maxcol)
|
| 395 |
+
self.file.write('\n')
|
| 396 |
+
self.col = 0
|
| 397 |
+
self.atbreak = 0
|
| 398 |
+
|
| 399 |
+
def send_literal_data(self, data):
|
| 400 |
+
self.file.write(data)
|
| 401 |
+
i = data.rfind('\n')
|
| 402 |
+
if i >= 0:
|
| 403 |
+
self.col = 0
|
| 404 |
+
data = data[i+1:]
|
| 405 |
+
data = data.expandtabs()
|
| 406 |
+
self.col = self.col + len(data)
|
| 407 |
+
self.atbreak = 0
|
| 408 |
+
|
| 409 |
+
def send_flowing_data(self, data):
|
| 410 |
+
if not data: return
|
| 411 |
+
atbreak = self.atbreak or data[0].isspace()
|
| 412 |
+
col = self.col
|
| 413 |
+
maxcol = self.maxcol
|
| 414 |
+
write = self.file.write
|
| 415 |
+
for word in data.split():
|
| 416 |
+
if atbreak:
|
| 417 |
+
if col + len(word) >= maxcol:
|
| 418 |
+
write('\n')
|
| 419 |
+
col = 0
|
| 420 |
+
else:
|
| 421 |
+
write(' ')
|
| 422 |
+
col = col + 1
|
| 423 |
+
write(word)
|
| 424 |
+
col = col + len(word)
|
| 425 |
+
atbreak = 1
|
| 426 |
+
self.col = col
|
| 427 |
+
self.atbreak = data[-1].isspace()
|
| 428 |
+
|
| 429 |
+
|
| 430 |
+
def test(file = None):
|
| 431 |
+
w = DumbWriter()
|
| 432 |
+
f = AbstractFormatter(w)
|
| 433 |
+
if file is not None:
|
| 434 |
+
fp = open(file)
|
| 435 |
+
elif sys.argv[1:]:
|
| 436 |
+
fp = open(sys.argv[1])
|
| 437 |
+
else:
|
| 438 |
+
fp = sys.stdin
|
| 439 |
+
try:
|
| 440 |
+
for line in fp:
|
| 441 |
+
if line == '\n':
|
| 442 |
+
f.end_paragraph(1)
|
| 443 |
+
else:
|
| 444 |
+
f.add_flowing_data(line)
|
| 445 |
+
finally:
|
| 446 |
+
if fp is not sys.stdin:
|
| 447 |
+
fp.close()
|
| 448 |
+
f.end_paragraph(0)
|
| 449 |
+
|
| 450 |
+
|
| 451 |
+
if __name__ == '__main__':
|
| 452 |
+
test()
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/functools.py
ADDED
|
@@ -0,0 +1,976 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""functools.py - Tools for working with functions and callable objects
|
| 2 |
+
"""
|
| 3 |
+
# Python module wrapper for _functools C module
|
| 4 |
+
# to allow utilities written in Python to be added
|
| 5 |
+
# to the functools module.
|
| 6 |
+
# Written by Nick Coghlan <ncoghlan at gmail.com>,
|
| 7 |
+
# Raymond Hettinger <python at rcn.com>,
|
| 8 |
+
# and Łukasz Langa <lukasz at langa.pl>.
|
| 9 |
+
# Copyright (C) 2006-2013 Python Software Foundation.
|
| 10 |
+
# See C source code for _functools credits/copyright
|
| 11 |
+
|
| 12 |
+
__all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES',
|
| 13 |
+
'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce', 'partial',
|
| 14 |
+
'partialmethod', 'singledispatch', 'singledispatchmethod',
|
| 15 |
+
"cached_property"]
|
| 16 |
+
|
| 17 |
+
from abc import get_cache_token
|
| 18 |
+
from collections import namedtuple
|
| 19 |
+
# import types, weakref # Deferred to single_dispatch()
|
| 20 |
+
from reprlib import recursive_repr
|
| 21 |
+
from _thread import RLock
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
################################################################################
|
| 25 |
+
### update_wrapper() and wraps() decorator
|
| 26 |
+
################################################################################
|
| 27 |
+
|
| 28 |
+
# update_wrapper() and wraps() are tools to help write
|
| 29 |
+
# wrapper functions that can handle naive introspection
|
| 30 |
+
|
| 31 |
+
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',
|
| 32 |
+
'__annotations__')
|
| 33 |
+
WRAPPER_UPDATES = ('__dict__',)
|
| 34 |
+
def update_wrapper(wrapper,
|
| 35 |
+
wrapped,
|
| 36 |
+
assigned = WRAPPER_ASSIGNMENTS,
|
| 37 |
+
updated = WRAPPER_UPDATES):
|
| 38 |
+
"""Update a wrapper function to look like the wrapped function
|
| 39 |
+
|
| 40 |
+
wrapper is the function to be updated
|
| 41 |
+
wrapped is the original function
|
| 42 |
+
assigned is a tuple naming the attributes assigned directly
|
| 43 |
+
from the wrapped function to the wrapper function (defaults to
|
| 44 |
+
functools.WRAPPER_ASSIGNMENTS)
|
| 45 |
+
updated is a tuple naming the attributes of the wrapper that
|
| 46 |
+
are updated with the corresponding attribute from the wrapped
|
| 47 |
+
function (defaults to functools.WRAPPER_UPDATES)
|
| 48 |
+
"""
|
| 49 |
+
for attr in assigned:
|
| 50 |
+
try:
|
| 51 |
+
value = getattr(wrapped, attr)
|
| 52 |
+
except AttributeError:
|
| 53 |
+
pass
|
| 54 |
+
else:
|
| 55 |
+
setattr(wrapper, attr, value)
|
| 56 |
+
for attr in updated:
|
| 57 |
+
getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
|
| 58 |
+
# Issue #17482: set __wrapped__ last so we don't inadvertently copy it
|
| 59 |
+
# from the wrapped function when updating __dict__
|
| 60 |
+
wrapper.__wrapped__ = wrapped
|
| 61 |
+
# Return the wrapper so this can be used as a decorator via partial()
|
| 62 |
+
return wrapper
|
| 63 |
+
|
| 64 |
+
def wraps(wrapped,
|
| 65 |
+
assigned = WRAPPER_ASSIGNMENTS,
|
| 66 |
+
updated = WRAPPER_UPDATES):
|
| 67 |
+
"""Decorator factory to apply update_wrapper() to a wrapper function
|
| 68 |
+
|
| 69 |
+
Returns a decorator that invokes update_wrapper() with the decorated
|
| 70 |
+
function as the wrapper argument and the arguments to wraps() as the
|
| 71 |
+
remaining arguments. Default arguments are as for update_wrapper().
|
| 72 |
+
This is a convenience function to simplify applying partial() to
|
| 73 |
+
update_wrapper().
|
| 74 |
+
"""
|
| 75 |
+
return partial(update_wrapper, wrapped=wrapped,
|
| 76 |
+
assigned=assigned, updated=updated)
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
################################################################################
|
| 80 |
+
### total_ordering class decorator
|
| 81 |
+
################################################################################
|
| 82 |
+
|
| 83 |
+
# The total ordering functions all invoke the root magic method directly
|
| 84 |
+
# rather than using the corresponding operator. This avoids possible
|
| 85 |
+
# infinite recursion that could occur when the operator dispatch logic
|
| 86 |
+
# detects a NotImplemented result and then calls a reflected method.
|
| 87 |
+
|
| 88 |
+
def _gt_from_lt(self, other, NotImplemented=NotImplemented):
|
| 89 |
+
'Return a > b. Computed by @total_ordering from (not a < b) and (a != b).'
|
| 90 |
+
op_result = self.__lt__(other)
|
| 91 |
+
if op_result is NotImplemented:
|
| 92 |
+
return op_result
|
| 93 |
+
return not op_result and self != other
|
| 94 |
+
|
| 95 |
+
def _le_from_lt(self, other, NotImplemented=NotImplemented):
|
| 96 |
+
'Return a <= b. Computed by @total_ordering from (a < b) or (a == b).'
|
| 97 |
+
op_result = self.__lt__(other)
|
| 98 |
+
return op_result or self == other
|
| 99 |
+
|
| 100 |
+
def _ge_from_lt(self, other, NotImplemented=NotImplemented):
|
| 101 |
+
'Return a >= b. Computed by @total_ordering from (not a < b).'
|
| 102 |
+
op_result = self.__lt__(other)
|
| 103 |
+
if op_result is NotImplemented:
|
| 104 |
+
return op_result
|
| 105 |
+
return not op_result
|
| 106 |
+
|
| 107 |
+
def _ge_from_le(self, other, NotImplemented=NotImplemented):
|
| 108 |
+
'Return a >= b. Computed by @total_ordering from (not a <= b) or (a == b).'
|
| 109 |
+
op_result = self.__le__(other)
|
| 110 |
+
if op_result is NotImplemented:
|
| 111 |
+
return op_result
|
| 112 |
+
return not op_result or self == other
|
| 113 |
+
|
| 114 |
+
def _lt_from_le(self, other, NotImplemented=NotImplemented):
|
| 115 |
+
'Return a < b. Computed by @total_ordering from (a <= b) and (a != b).'
|
| 116 |
+
op_result = self.__le__(other)
|
| 117 |
+
if op_result is NotImplemented:
|
| 118 |
+
return op_result
|
| 119 |
+
return op_result and self != other
|
| 120 |
+
|
| 121 |
+
def _gt_from_le(self, other, NotImplemented=NotImplemented):
|
| 122 |
+
'Return a > b. Computed by @total_ordering from (not a <= b).'
|
| 123 |
+
op_result = self.__le__(other)
|
| 124 |
+
if op_result is NotImplemented:
|
| 125 |
+
return op_result
|
| 126 |
+
return not op_result
|
| 127 |
+
|
| 128 |
+
def _lt_from_gt(self, other, NotImplemented=NotImplemented):
|
| 129 |
+
'Return a < b. Computed by @total_ordering from (not a > b) and (a != b).'
|
| 130 |
+
op_result = self.__gt__(other)
|
| 131 |
+
if op_result is NotImplemented:
|
| 132 |
+
return op_result
|
| 133 |
+
return not op_result and self != other
|
| 134 |
+
|
| 135 |
+
def _ge_from_gt(self, other, NotImplemented=NotImplemented):
|
| 136 |
+
'Return a >= b. Computed by @total_ordering from (a > b) or (a == b).'
|
| 137 |
+
op_result = self.__gt__(other)
|
| 138 |
+
return op_result or self == other
|
| 139 |
+
|
| 140 |
+
def _le_from_gt(self, other, NotImplemented=NotImplemented):
|
| 141 |
+
'Return a <= b. Computed by @total_ordering from (not a > b).'
|
| 142 |
+
op_result = self.__gt__(other)
|
| 143 |
+
if op_result is NotImplemented:
|
| 144 |
+
return op_result
|
| 145 |
+
return not op_result
|
| 146 |
+
|
| 147 |
+
def _le_from_ge(self, other, NotImplemented=NotImplemented):
|
| 148 |
+
'Return a <= b. Computed by @total_ordering from (not a >= b) or (a == b).'
|
| 149 |
+
op_result = self.__ge__(other)
|
| 150 |
+
if op_result is NotImplemented:
|
| 151 |
+
return op_result
|
| 152 |
+
return not op_result or self == other
|
| 153 |
+
|
| 154 |
+
def _gt_from_ge(self, other, NotImplemented=NotImplemented):
|
| 155 |
+
'Return a > b. Computed by @total_ordering from (a >= b) and (a != b).'
|
| 156 |
+
op_result = self.__ge__(other)
|
| 157 |
+
if op_result is NotImplemented:
|
| 158 |
+
return op_result
|
| 159 |
+
return op_result and self != other
|
| 160 |
+
|
| 161 |
+
def _lt_from_ge(self, other, NotImplemented=NotImplemented):
|
| 162 |
+
'Return a < b. Computed by @total_ordering from (not a >= b).'
|
| 163 |
+
op_result = self.__ge__(other)
|
| 164 |
+
if op_result is NotImplemented:
|
| 165 |
+
return op_result
|
| 166 |
+
return not op_result
|
| 167 |
+
|
| 168 |
+
_convert = {
|
| 169 |
+
'__lt__': [('__gt__', _gt_from_lt),
|
| 170 |
+
('__le__', _le_from_lt),
|
| 171 |
+
('__ge__', _ge_from_lt)],
|
| 172 |
+
'__le__': [('__ge__', _ge_from_le),
|
| 173 |
+
('__lt__', _lt_from_le),
|
| 174 |
+
('__gt__', _gt_from_le)],
|
| 175 |
+
'__gt__': [('__lt__', _lt_from_gt),
|
| 176 |
+
('__ge__', _ge_from_gt),
|
| 177 |
+
('__le__', _le_from_gt)],
|
| 178 |
+
'__ge__': [('__le__', _le_from_ge),
|
| 179 |
+
('__gt__', _gt_from_ge),
|
| 180 |
+
('__lt__', _lt_from_ge)]
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
def total_ordering(cls):
|
| 184 |
+
"""Class decorator that fills in missing ordering methods"""
|
| 185 |
+
# Find user-defined comparisons (not those inherited from object).
|
| 186 |
+
roots = {op for op in _convert if getattr(cls, op, None) is not getattr(object, op, None)}
|
| 187 |
+
if not roots:
|
| 188 |
+
raise ValueError('must define at least one ordering operation: < > <= >=')
|
| 189 |
+
root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__
|
| 190 |
+
for opname, opfunc in _convert[root]:
|
| 191 |
+
if opname not in roots:
|
| 192 |
+
opfunc.__name__ = opname
|
| 193 |
+
setattr(cls, opname, opfunc)
|
| 194 |
+
return cls
|
| 195 |
+
|
| 196 |
+
|
| 197 |
+
################################################################################
|
| 198 |
+
### cmp_to_key() function converter
|
| 199 |
+
################################################################################
|
| 200 |
+
|
| 201 |
+
def cmp_to_key(mycmp):
|
| 202 |
+
"""Convert a cmp= function into a key= function"""
|
| 203 |
+
class K(object):
|
| 204 |
+
__slots__ = ['obj']
|
| 205 |
+
def __init__(self, obj):
|
| 206 |
+
self.obj = obj
|
| 207 |
+
def __lt__(self, other):
|
| 208 |
+
return mycmp(self.obj, other.obj) < 0
|
| 209 |
+
def __gt__(self, other):
|
| 210 |
+
return mycmp(self.obj, other.obj) > 0
|
| 211 |
+
def __eq__(self, other):
|
| 212 |
+
return mycmp(self.obj, other.obj) == 0
|
| 213 |
+
def __le__(self, other):
|
| 214 |
+
return mycmp(self.obj, other.obj) <= 0
|
| 215 |
+
def __ge__(self, other):
|
| 216 |
+
return mycmp(self.obj, other.obj) >= 0
|
| 217 |
+
__hash__ = None
|
| 218 |
+
return K
|
| 219 |
+
|
| 220 |
+
try:
|
| 221 |
+
from _functools import cmp_to_key
|
| 222 |
+
except ImportError:
|
| 223 |
+
pass
|
| 224 |
+
|
| 225 |
+
|
| 226 |
+
################################################################################
|
| 227 |
+
### reduce() sequence to a single item
|
| 228 |
+
################################################################################
|
| 229 |
+
|
| 230 |
+
_initial_missing = object()
|
| 231 |
+
|
| 232 |
+
def reduce(function, sequence, initial=_initial_missing):
|
| 233 |
+
"""
|
| 234 |
+
reduce(function, sequence[, initial]) -> value
|
| 235 |
+
|
| 236 |
+
Apply a function of two arguments cumulatively to the items of a sequence,
|
| 237 |
+
from left to right, so as to reduce the sequence to a single value.
|
| 238 |
+
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
|
| 239 |
+
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
|
| 240 |
+
of the sequence in the calculation, and serves as a default when the
|
| 241 |
+
sequence is empty.
|
| 242 |
+
"""
|
| 243 |
+
|
| 244 |
+
it = iter(sequence)
|
| 245 |
+
|
| 246 |
+
if initial is _initial_missing:
|
| 247 |
+
try:
|
| 248 |
+
value = next(it)
|
| 249 |
+
except StopIteration:
|
| 250 |
+
raise TypeError("reduce() of empty sequence with no initial value") from None
|
| 251 |
+
else:
|
| 252 |
+
value = initial
|
| 253 |
+
|
| 254 |
+
for element in it:
|
| 255 |
+
value = function(value, element)
|
| 256 |
+
|
| 257 |
+
return value
|
| 258 |
+
|
| 259 |
+
try:
|
| 260 |
+
from _functools import reduce
|
| 261 |
+
except ImportError:
|
| 262 |
+
pass
|
| 263 |
+
|
| 264 |
+
|
| 265 |
+
################################################################################
|
| 266 |
+
### partial() argument application
|
| 267 |
+
################################################################################
|
| 268 |
+
|
| 269 |
+
# Purely functional, no descriptor behaviour
|
| 270 |
+
class partial:
|
| 271 |
+
"""New function with partial application of the given arguments
|
| 272 |
+
and keywords.
|
| 273 |
+
"""
|
| 274 |
+
|
| 275 |
+
__slots__ = "func", "args", "keywords", "__dict__", "__weakref__"
|
| 276 |
+
|
| 277 |
+
def __new__(cls, func, /, *args, **keywords):
|
| 278 |
+
if not callable(func):
|
| 279 |
+
raise TypeError("the first argument must be callable")
|
| 280 |
+
|
| 281 |
+
if hasattr(func, "func"):
|
| 282 |
+
args = func.args + args
|
| 283 |
+
keywords = {**func.keywords, **keywords}
|
| 284 |
+
func = func.func
|
| 285 |
+
|
| 286 |
+
self = super(partial, cls).__new__(cls)
|
| 287 |
+
|
| 288 |
+
self.func = func
|
| 289 |
+
self.args = args
|
| 290 |
+
self.keywords = keywords
|
| 291 |
+
return self
|
| 292 |
+
|
| 293 |
+
def __call__(self, /, *args, **keywords):
|
| 294 |
+
keywords = {**self.keywords, **keywords}
|
| 295 |
+
return self.func(*self.args, *args, **keywords)
|
| 296 |
+
|
| 297 |
+
@recursive_repr()
|
| 298 |
+
def __repr__(self):
|
| 299 |
+
qualname = type(self).__qualname__
|
| 300 |
+
args = [repr(self.func)]
|
| 301 |
+
args.extend(repr(x) for x in self.args)
|
| 302 |
+
args.extend(f"{k}={v!r}" for (k, v) in self.keywords.items())
|
| 303 |
+
if type(self).__module__ == "functools":
|
| 304 |
+
return f"functools.{qualname}({', '.join(args)})"
|
| 305 |
+
return f"{qualname}({', '.join(args)})"
|
| 306 |
+
|
| 307 |
+
def __reduce__(self):
|
| 308 |
+
return type(self), (self.func,), (self.func, self.args,
|
| 309 |
+
self.keywords or None, self.__dict__ or None)
|
| 310 |
+
|
| 311 |
+
def __setstate__(self, state):
|
| 312 |
+
if not isinstance(state, tuple):
|
| 313 |
+
raise TypeError("argument to __setstate__ must be a tuple")
|
| 314 |
+
if len(state) != 4:
|
| 315 |
+
raise TypeError(f"expected 4 items in state, got {len(state)}")
|
| 316 |
+
func, args, kwds, namespace = state
|
| 317 |
+
if (not callable(func) or not isinstance(args, tuple) or
|
| 318 |
+
(kwds is not None and not isinstance(kwds, dict)) or
|
| 319 |
+
(namespace is not None and not isinstance(namespace, dict))):
|
| 320 |
+
raise TypeError("invalid partial state")
|
| 321 |
+
|
| 322 |
+
args = tuple(args) # just in case it's a subclass
|
| 323 |
+
if kwds is None:
|
| 324 |
+
kwds = {}
|
| 325 |
+
elif type(kwds) is not dict: # XXX does it need to be *exactly* dict?
|
| 326 |
+
kwds = dict(kwds)
|
| 327 |
+
if namespace is None:
|
| 328 |
+
namespace = {}
|
| 329 |
+
|
| 330 |
+
self.__dict__ = namespace
|
| 331 |
+
self.func = func
|
| 332 |
+
self.args = args
|
| 333 |
+
self.keywords = kwds
|
| 334 |
+
|
| 335 |
+
try:
|
| 336 |
+
from _functools import partial
|
| 337 |
+
except ImportError:
|
| 338 |
+
pass
|
| 339 |
+
|
| 340 |
+
# Descriptor version
|
| 341 |
+
class partialmethod(object):
|
| 342 |
+
"""Method descriptor with partial application of the given arguments
|
| 343 |
+
and keywords.
|
| 344 |
+
|
| 345 |
+
Supports wrapping existing descriptors and handles non-descriptor
|
| 346 |
+
callables as instance methods.
|
| 347 |
+
"""
|
| 348 |
+
|
| 349 |
+
def __init__(*args, **keywords):
|
| 350 |
+
if len(args) >= 2:
|
| 351 |
+
self, func, *args = args
|
| 352 |
+
elif not args:
|
| 353 |
+
raise TypeError("descriptor '__init__' of partialmethod "
|
| 354 |
+
"needs an argument")
|
| 355 |
+
elif 'func' in keywords:
|
| 356 |
+
func = keywords.pop('func')
|
| 357 |
+
self, *args = args
|
| 358 |
+
import warnings
|
| 359 |
+
warnings.warn("Passing 'func' as keyword argument is deprecated",
|
| 360 |
+
DeprecationWarning, stacklevel=2)
|
| 361 |
+
else:
|
| 362 |
+
raise TypeError("type 'partialmethod' takes at least one argument, "
|
| 363 |
+
"got %d" % (len(args)-1))
|
| 364 |
+
args = tuple(args)
|
| 365 |
+
|
| 366 |
+
if not callable(func) and not hasattr(func, "__get__"):
|
| 367 |
+
raise TypeError("{!r} is not callable or a descriptor"
|
| 368 |
+
.format(func))
|
| 369 |
+
|
| 370 |
+
# func could be a descriptor like classmethod which isn't callable,
|
| 371 |
+
# so we can't inherit from partial (it verifies func is callable)
|
| 372 |
+
if isinstance(func, partialmethod):
|
| 373 |
+
# flattening is mandatory in order to place cls/self before all
|
| 374 |
+
# other arguments
|
| 375 |
+
# it's also more efficient since only one function will be called
|
| 376 |
+
self.func = func.func
|
| 377 |
+
self.args = func.args + args
|
| 378 |
+
self.keywords = {**func.keywords, **keywords}
|
| 379 |
+
else:
|
| 380 |
+
self.func = func
|
| 381 |
+
self.args = args
|
| 382 |
+
self.keywords = keywords
|
| 383 |
+
__init__.__text_signature__ = '($self, func, /, *args, **keywords)'
|
| 384 |
+
|
| 385 |
+
def __repr__(self):
|
| 386 |
+
args = ", ".join(map(repr, self.args))
|
| 387 |
+
keywords = ", ".join("{}={!r}".format(k, v)
|
| 388 |
+
for k, v in self.keywords.items())
|
| 389 |
+
format_string = "{module}.{cls}({func}, {args}, {keywords})"
|
| 390 |
+
return format_string.format(module=self.__class__.__module__,
|
| 391 |
+
cls=self.__class__.__qualname__,
|
| 392 |
+
func=self.func,
|
| 393 |
+
args=args,
|
| 394 |
+
keywords=keywords)
|
| 395 |
+
|
| 396 |
+
def _make_unbound_method(self):
|
| 397 |
+
def _method(cls_or_self, /, *args, **keywords):
|
| 398 |
+
keywords = {**self.keywords, **keywords}
|
| 399 |
+
return self.func(cls_or_self, *self.args, *args, **keywords)
|
| 400 |
+
_method.__isabstractmethod__ = self.__isabstractmethod__
|
| 401 |
+
_method._partialmethod = self
|
| 402 |
+
return _method
|
| 403 |
+
|
| 404 |
+
def __get__(self, obj, cls=None):
|
| 405 |
+
get = getattr(self.func, "__get__", None)
|
| 406 |
+
result = None
|
| 407 |
+
if get is not None:
|
| 408 |
+
new_func = get(obj, cls)
|
| 409 |
+
if new_func is not self.func:
|
| 410 |
+
# Assume __get__ returning something new indicates the
|
| 411 |
+
# creation of an appropriate callable
|
| 412 |
+
result = partial(new_func, *self.args, **self.keywords)
|
| 413 |
+
try:
|
| 414 |
+
result.__self__ = new_func.__self__
|
| 415 |
+
except AttributeError:
|
| 416 |
+
pass
|
| 417 |
+
if result is None:
|
| 418 |
+
# If the underlying descriptor didn't do anything, treat this
|
| 419 |
+
# like an instance method
|
| 420 |
+
result = self._make_unbound_method().__get__(obj, cls)
|
| 421 |
+
return result
|
| 422 |
+
|
| 423 |
+
@property
|
| 424 |
+
def __isabstractmethod__(self):
|
| 425 |
+
return getattr(self.func, "__isabstractmethod__", False)
|
| 426 |
+
|
| 427 |
+
# Helper functions
|
| 428 |
+
|
| 429 |
+
def _unwrap_partial(func):
|
| 430 |
+
while isinstance(func, partial):
|
| 431 |
+
func = func.func
|
| 432 |
+
return func
|
| 433 |
+
|
| 434 |
+
################################################################################
|
| 435 |
+
### LRU Cache function decorator
|
| 436 |
+
################################################################################
|
| 437 |
+
|
| 438 |
+
_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])
|
| 439 |
+
|
| 440 |
+
class _HashedSeq(list):
|
| 441 |
+
""" This class guarantees that hash() will be called no more than once
|
| 442 |
+
per element. This is important because the lru_cache() will hash
|
| 443 |
+
the key multiple times on a cache miss.
|
| 444 |
+
|
| 445 |
+
"""
|
| 446 |
+
|
| 447 |
+
__slots__ = 'hashvalue'
|
| 448 |
+
|
| 449 |
+
def __init__(self, tup, hash=hash):
|
| 450 |
+
self[:] = tup
|
| 451 |
+
self.hashvalue = hash(tup)
|
| 452 |
+
|
| 453 |
+
def __hash__(self):
|
| 454 |
+
return self.hashvalue
|
| 455 |
+
|
| 456 |
+
def _make_key(args, kwds, typed,
|
| 457 |
+
kwd_mark = (object(),),
|
| 458 |
+
fasttypes = {int, str},
|
| 459 |
+
tuple=tuple, type=type, len=len):
|
| 460 |
+
"""Make a cache key from optionally typed positional and keyword arguments
|
| 461 |
+
|
| 462 |
+
The key is constructed in a way that is flat as possible rather than
|
| 463 |
+
as a nested structure that would take more memory.
|
| 464 |
+
|
| 465 |
+
If there is only a single argument and its data type is known to cache
|
| 466 |
+
its hash value, then that argument is returned without a wrapper. This
|
| 467 |
+
saves space and improves lookup speed.
|
| 468 |
+
|
| 469 |
+
"""
|
| 470 |
+
# All of code below relies on kwds preserving the order input by the user.
|
| 471 |
+
# Formerly, we sorted() the kwds before looping. The new way is *much*
|
| 472 |
+
# faster; however, it means that f(x=1, y=2) will now be treated as a
|
| 473 |
+
# distinct call from f(y=2, x=1) which will be cached separately.
|
| 474 |
+
key = args
|
| 475 |
+
if kwds:
|
| 476 |
+
key += kwd_mark
|
| 477 |
+
for item in kwds.items():
|
| 478 |
+
key += item
|
| 479 |
+
if typed:
|
| 480 |
+
key += tuple(type(v) for v in args)
|
| 481 |
+
if kwds:
|
| 482 |
+
key += tuple(type(v) for v in kwds.values())
|
| 483 |
+
elif len(key) == 1 and type(key[0]) in fasttypes:
|
| 484 |
+
return key[0]
|
| 485 |
+
return _HashedSeq(key)
|
| 486 |
+
|
| 487 |
+
def lru_cache(maxsize=128, typed=False):
|
| 488 |
+
"""Least-recently-used cache decorator.
|
| 489 |
+
|
| 490 |
+
If *maxsize* is set to None, the LRU features are disabled and the cache
|
| 491 |
+
can grow without bound.
|
| 492 |
+
|
| 493 |
+
If *typed* is True, arguments of different types will be cached separately.
|
| 494 |
+
For example, f(3.0) and f(3) will be treated as distinct calls with
|
| 495 |
+
distinct results.
|
| 496 |
+
|
| 497 |
+
Arguments to the cached function must be hashable.
|
| 498 |
+
|
| 499 |
+
View the cache statistics named tuple (hits, misses, maxsize, currsize)
|
| 500 |
+
with f.cache_info(). Clear the cache and statistics with f.cache_clear().
|
| 501 |
+
Access the underlying function with f.__wrapped__.
|
| 502 |
+
|
| 503 |
+
See: http://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)
|
| 504 |
+
|
| 505 |
+
"""
|
| 506 |
+
|
| 507 |
+
# Users should only access the lru_cache through its public API:
|
| 508 |
+
# cache_info, cache_clear, and f.__wrapped__
|
| 509 |
+
# The internals of the lru_cache are encapsulated for thread safety and
|
| 510 |
+
# to allow the implementation to change (including a possible C version).
|
| 511 |
+
|
| 512 |
+
if isinstance(maxsize, int):
|
| 513 |
+
# Negative maxsize is treated as 0
|
| 514 |
+
if maxsize < 0:
|
| 515 |
+
maxsize = 0
|
| 516 |
+
elif callable(maxsize) and isinstance(typed, bool):
|
| 517 |
+
# The user_function was passed in directly via the maxsize argument
|
| 518 |
+
user_function, maxsize = maxsize, 128
|
| 519 |
+
wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)
|
| 520 |
+
return update_wrapper(wrapper, user_function)
|
| 521 |
+
elif maxsize is not None:
|
| 522 |
+
raise TypeError(
|
| 523 |
+
'Expected first argument to be an integer, a callable, or None')
|
| 524 |
+
|
| 525 |
+
def decorating_function(user_function):
|
| 526 |
+
wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)
|
| 527 |
+
return update_wrapper(wrapper, user_function)
|
| 528 |
+
|
| 529 |
+
return decorating_function
|
| 530 |
+
|
| 531 |
+
def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):
|
| 532 |
+
# Constants shared by all lru cache instances:
|
| 533 |
+
sentinel = object() # unique object used to signal cache misses
|
| 534 |
+
make_key = _make_key # build a key from the function arguments
|
| 535 |
+
PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields
|
| 536 |
+
|
| 537 |
+
cache = {}
|
| 538 |
+
hits = misses = 0
|
| 539 |
+
full = False
|
| 540 |
+
cache_get = cache.get # bound method to lookup a key or return None
|
| 541 |
+
cache_len = cache.__len__ # get cache size without calling len()
|
| 542 |
+
lock = RLock() # because linkedlist updates aren't threadsafe
|
| 543 |
+
root = [] # root of the circular doubly linked list
|
| 544 |
+
root[:] = [root, root, None, None] # initialize by pointing to self
|
| 545 |
+
|
| 546 |
+
if maxsize == 0:
|
| 547 |
+
|
| 548 |
+
def wrapper(*args, **kwds):
|
| 549 |
+
# No caching -- just a statistics update
|
| 550 |
+
nonlocal misses
|
| 551 |
+
misses += 1
|
| 552 |
+
result = user_function(*args, **kwds)
|
| 553 |
+
return result
|
| 554 |
+
|
| 555 |
+
elif maxsize is None:
|
| 556 |
+
|
| 557 |
+
def wrapper(*args, **kwds):
|
| 558 |
+
# Simple caching without ordering or size limit
|
| 559 |
+
nonlocal hits, misses
|
| 560 |
+
key = make_key(args, kwds, typed)
|
| 561 |
+
result = cache_get(key, sentinel)
|
| 562 |
+
if result is not sentinel:
|
| 563 |
+
hits += 1
|
| 564 |
+
return result
|
| 565 |
+
misses += 1
|
| 566 |
+
result = user_function(*args, **kwds)
|
| 567 |
+
cache[key] = result
|
| 568 |
+
return result
|
| 569 |
+
|
| 570 |
+
else:
|
| 571 |
+
|
| 572 |
+
def wrapper(*args, **kwds):
|
| 573 |
+
# Size limited caching that tracks accesses by recency
|
| 574 |
+
nonlocal root, hits, misses, full
|
| 575 |
+
key = make_key(args, kwds, typed)
|
| 576 |
+
with lock:
|
| 577 |
+
link = cache_get(key)
|
| 578 |
+
if link is not None:
|
| 579 |
+
# Move the link to the front of the circular queue
|
| 580 |
+
link_prev, link_next, _key, result = link
|
| 581 |
+
link_prev[NEXT] = link_next
|
| 582 |
+
link_next[PREV] = link_prev
|
| 583 |
+
last = root[PREV]
|
| 584 |
+
last[NEXT] = root[PREV] = link
|
| 585 |
+
link[PREV] = last
|
| 586 |
+
link[NEXT] = root
|
| 587 |
+
hits += 1
|
| 588 |
+
return result
|
| 589 |
+
misses += 1
|
| 590 |
+
result = user_function(*args, **kwds)
|
| 591 |
+
with lock:
|
| 592 |
+
if key in cache:
|
| 593 |
+
# Getting here means that this same key was added to the
|
| 594 |
+
# cache while the lock was released. Since the link
|
| 595 |
+
# update is already done, we need only return the
|
| 596 |
+
# computed result and update the count of misses.
|
| 597 |
+
pass
|
| 598 |
+
elif full:
|
| 599 |
+
# Use the old root to store the new key and result.
|
| 600 |
+
oldroot = root
|
| 601 |
+
oldroot[KEY] = key
|
| 602 |
+
oldroot[RESULT] = result
|
| 603 |
+
# Empty the oldest link and make it the new root.
|
| 604 |
+
# Keep a reference to the old key and old result to
|
| 605 |
+
# prevent their ref counts from going to zero during the
|
| 606 |
+
# update. That will prevent potentially arbitrary object
|
| 607 |
+
# clean-up code (i.e. __del__) from running while we're
|
| 608 |
+
# still adjusting the links.
|
| 609 |
+
root = oldroot[NEXT]
|
| 610 |
+
oldkey = root[KEY]
|
| 611 |
+
oldresult = root[RESULT]
|
| 612 |
+
root[KEY] = root[RESULT] = None
|
| 613 |
+
# Now update the cache dictionary.
|
| 614 |
+
del cache[oldkey]
|
| 615 |
+
# Save the potentially reentrant cache[key] assignment
|
| 616 |
+
# for last, after the root and links have been put in
|
| 617 |
+
# a consistent state.
|
| 618 |
+
cache[key] = oldroot
|
| 619 |
+
else:
|
| 620 |
+
# Put result in a new link at the front of the queue.
|
| 621 |
+
last = root[PREV]
|
| 622 |
+
link = [last, root, key, result]
|
| 623 |
+
last[NEXT] = root[PREV] = cache[key] = link
|
| 624 |
+
# Use the cache_len bound method instead of the len() function
|
| 625 |
+
# which could potentially be wrapped in an lru_cache itself.
|
| 626 |
+
full = (cache_len() >= maxsize)
|
| 627 |
+
return result
|
| 628 |
+
|
| 629 |
+
def cache_info():
|
| 630 |
+
"""Report cache statistics"""
|
| 631 |
+
with lock:
|
| 632 |
+
return _CacheInfo(hits, misses, maxsize, cache_len())
|
| 633 |
+
|
| 634 |
+
def cache_clear():
|
| 635 |
+
"""Clear the cache and cache statistics"""
|
| 636 |
+
nonlocal hits, misses, full
|
| 637 |
+
with lock:
|
| 638 |
+
cache.clear()
|
| 639 |
+
root[:] = [root, root, None, None]
|
| 640 |
+
hits = misses = 0
|
| 641 |
+
full = False
|
| 642 |
+
|
| 643 |
+
wrapper.cache_info = cache_info
|
| 644 |
+
wrapper.cache_clear = cache_clear
|
| 645 |
+
return wrapper
|
| 646 |
+
|
| 647 |
+
try:
|
| 648 |
+
from _functools import _lru_cache_wrapper
|
| 649 |
+
except ImportError:
|
| 650 |
+
pass
|
| 651 |
+
|
| 652 |
+
|
| 653 |
+
################################################################################
|
| 654 |
+
### singledispatch() - single-dispatch generic function decorator
|
| 655 |
+
################################################################################
|
| 656 |
+
|
| 657 |
+
def _c3_merge(sequences):
|
| 658 |
+
"""Merges MROs in *sequences* to a single MRO using the C3 algorithm.
|
| 659 |
+
|
| 660 |
+
Adapted from http://www.python.org/download/releases/2.3/mro/.
|
| 661 |
+
|
| 662 |
+
"""
|
| 663 |
+
result = []
|
| 664 |
+
while True:
|
| 665 |
+
sequences = [s for s in sequences if s] # purge empty sequences
|
| 666 |
+
if not sequences:
|
| 667 |
+
return result
|
| 668 |
+
for s1 in sequences: # find merge candidates among seq heads
|
| 669 |
+
candidate = s1[0]
|
| 670 |
+
for s2 in sequences:
|
| 671 |
+
if candidate in s2[1:]:
|
| 672 |
+
candidate = None
|
| 673 |
+
break # reject the current head, it appears later
|
| 674 |
+
else:
|
| 675 |
+
break
|
| 676 |
+
if candidate is None:
|
| 677 |
+
raise RuntimeError("Inconsistent hierarchy")
|
| 678 |
+
result.append(candidate)
|
| 679 |
+
# remove the chosen candidate
|
| 680 |
+
for seq in sequences:
|
| 681 |
+
if seq[0] == candidate:
|
| 682 |
+
del seq[0]
|
| 683 |
+
|
| 684 |
+
def _c3_mro(cls, abcs=None):
|
| 685 |
+
"""Computes the method resolution order using extended C3 linearization.
|
| 686 |
+
|
| 687 |
+
If no *abcs* are given, the algorithm works exactly like the built-in C3
|
| 688 |
+
linearization used for method resolution.
|
| 689 |
+
|
| 690 |
+
If given, *abcs* is a list of abstract base classes that should be inserted
|
| 691 |
+
into the resulting MRO. Unrelated ABCs are ignored and don't end up in the
|
| 692 |
+
result. The algorithm inserts ABCs where their functionality is introduced,
|
| 693 |
+
i.e. issubclass(cls, abc) returns True for the class itself but returns
|
| 694 |
+
False for all its direct base classes. Implicit ABCs for a given class
|
| 695 |
+
(either registered or inferred from the presence of a special method like
|
| 696 |
+
__len__) are inserted directly after the last ABC explicitly listed in the
|
| 697 |
+
MRO of said class. If two implicit ABCs end up next to each other in the
|
| 698 |
+
resulting MRO, their ordering depends on the order of types in *abcs*.
|
| 699 |
+
|
| 700 |
+
"""
|
| 701 |
+
for i, base in enumerate(reversed(cls.__bases__)):
|
| 702 |
+
if hasattr(base, '__abstractmethods__'):
|
| 703 |
+
boundary = len(cls.__bases__) - i
|
| 704 |
+
break # Bases up to the last explicit ABC are considered first.
|
| 705 |
+
else:
|
| 706 |
+
boundary = 0
|
| 707 |
+
abcs = list(abcs) if abcs else []
|
| 708 |
+
explicit_bases = list(cls.__bases__[:boundary])
|
| 709 |
+
abstract_bases = []
|
| 710 |
+
other_bases = list(cls.__bases__[boundary:])
|
| 711 |
+
for base in abcs:
|
| 712 |
+
if issubclass(cls, base) and not any(
|
| 713 |
+
issubclass(b, base) for b in cls.__bases__
|
| 714 |
+
):
|
| 715 |
+
# If *cls* is the class that introduces behaviour described by
|
| 716 |
+
# an ABC *base*, insert said ABC to its MRO.
|
| 717 |
+
abstract_bases.append(base)
|
| 718 |
+
for base in abstract_bases:
|
| 719 |
+
abcs.remove(base)
|
| 720 |
+
explicit_c3_mros = [_c3_mro(base, abcs=abcs) for base in explicit_bases]
|
| 721 |
+
abstract_c3_mros = [_c3_mro(base, abcs=abcs) for base in abstract_bases]
|
| 722 |
+
other_c3_mros = [_c3_mro(base, abcs=abcs) for base in other_bases]
|
| 723 |
+
return _c3_merge(
|
| 724 |
+
[[cls]] +
|
| 725 |
+
explicit_c3_mros + abstract_c3_mros + other_c3_mros +
|
| 726 |
+
[explicit_bases] + [abstract_bases] + [other_bases]
|
| 727 |
+
)
|
| 728 |
+
|
| 729 |
+
def _compose_mro(cls, types):
|
| 730 |
+
"""Calculates the method resolution order for a given class *cls*.
|
| 731 |
+
|
| 732 |
+
Includes relevant abstract base classes (with their respective bases) from
|
| 733 |
+
the *types* iterable. Uses a modified C3 linearization algorithm.
|
| 734 |
+
|
| 735 |
+
"""
|
| 736 |
+
bases = set(cls.__mro__)
|
| 737 |
+
# Remove entries which are already present in the __mro__ or unrelated.
|
| 738 |
+
def is_related(typ):
|
| 739 |
+
return (typ not in bases and hasattr(typ, '__mro__')
|
| 740 |
+
and issubclass(cls, typ))
|
| 741 |
+
types = [n for n in types if is_related(n)]
|
| 742 |
+
# Remove entries which are strict bases of other entries (they will end up
|
| 743 |
+
# in the MRO anyway.
|
| 744 |
+
def is_strict_base(typ):
|
| 745 |
+
for other in types:
|
| 746 |
+
if typ != other and typ in other.__mro__:
|
| 747 |
+
return True
|
| 748 |
+
return False
|
| 749 |
+
types = [n for n in types if not is_strict_base(n)]
|
| 750 |
+
# Subclasses of the ABCs in *types* which are also implemented by
|
| 751 |
+
# *cls* can be used to stabilize ABC ordering.
|
| 752 |
+
type_set = set(types)
|
| 753 |
+
mro = []
|
| 754 |
+
for typ in types:
|
| 755 |
+
found = []
|
| 756 |
+
for sub in typ.__subclasses__():
|
| 757 |
+
if sub not in bases and issubclass(cls, sub):
|
| 758 |
+
found.append([s for s in sub.__mro__ if s in type_set])
|
| 759 |
+
if not found:
|
| 760 |
+
mro.append(typ)
|
| 761 |
+
continue
|
| 762 |
+
# Favor subclasses with the biggest number of useful bases
|
| 763 |
+
found.sort(key=len, reverse=True)
|
| 764 |
+
for sub in found:
|
| 765 |
+
for subcls in sub:
|
| 766 |
+
if subcls not in mro:
|
| 767 |
+
mro.append(subcls)
|
| 768 |
+
return _c3_mro(cls, abcs=mro)
|
| 769 |
+
|
| 770 |
+
def _find_impl(cls, registry):
|
| 771 |
+
"""Returns the best matching implementation from *registry* for type *cls*.
|
| 772 |
+
|
| 773 |
+
Where there is no registered implementation for a specific type, its method
|
| 774 |
+
resolution order is used to find a more generic implementation.
|
| 775 |
+
|
| 776 |
+
Note: if *registry* does not contain an implementation for the base
|
| 777 |
+
*object* type, this function may return None.
|
| 778 |
+
|
| 779 |
+
"""
|
| 780 |
+
mro = _compose_mro(cls, registry.keys())
|
| 781 |
+
match = None
|
| 782 |
+
for t in mro:
|
| 783 |
+
if match is not None:
|
| 784 |
+
# If *match* is an implicit ABC but there is another unrelated,
|
| 785 |
+
# equally matching implicit ABC, refuse the temptation to guess.
|
| 786 |
+
if (t in registry and t not in cls.__mro__
|
| 787 |
+
and match not in cls.__mro__
|
| 788 |
+
and not issubclass(match, t)):
|
| 789 |
+
raise RuntimeError("Ambiguous dispatch: {} or {}".format(
|
| 790 |
+
match, t))
|
| 791 |
+
break
|
| 792 |
+
if t in registry:
|
| 793 |
+
match = t
|
| 794 |
+
return registry.get(match)
|
| 795 |
+
|
| 796 |
+
def singledispatch(func):
|
| 797 |
+
"""Single-dispatch generic function decorator.
|
| 798 |
+
|
| 799 |
+
Transforms a function into a generic function, which can have different
|
| 800 |
+
behaviours depending upon the type of its first argument. The decorated
|
| 801 |
+
function acts as the default implementation, and additional
|
| 802 |
+
implementations can be registered using the register() attribute of the
|
| 803 |
+
generic function.
|
| 804 |
+
"""
|
| 805 |
+
# There are many programs that use functools without singledispatch, so we
|
| 806 |
+
# trade-off making singledispatch marginally slower for the benefit of
|
| 807 |
+
# making start-up of such applications slightly faster.
|
| 808 |
+
import types, weakref
|
| 809 |
+
|
| 810 |
+
registry = {}
|
| 811 |
+
dispatch_cache = weakref.WeakKeyDictionary()
|
| 812 |
+
cache_token = None
|
| 813 |
+
|
| 814 |
+
def dispatch(cls):
|
| 815 |
+
"""generic_func.dispatch(cls) -> <function implementation>
|
| 816 |
+
|
| 817 |
+
Runs the dispatch algorithm to return the best available implementation
|
| 818 |
+
for the given *cls* registered on *generic_func*.
|
| 819 |
+
|
| 820 |
+
"""
|
| 821 |
+
nonlocal cache_token
|
| 822 |
+
if cache_token is not None:
|
| 823 |
+
current_token = get_cache_token()
|
| 824 |
+
if cache_token != current_token:
|
| 825 |
+
dispatch_cache.clear()
|
| 826 |
+
cache_token = current_token
|
| 827 |
+
try:
|
| 828 |
+
impl = dispatch_cache[cls]
|
| 829 |
+
except KeyError:
|
| 830 |
+
try:
|
| 831 |
+
impl = registry[cls]
|
| 832 |
+
except KeyError:
|
| 833 |
+
impl = _find_impl(cls, registry)
|
| 834 |
+
dispatch_cache[cls] = impl
|
| 835 |
+
return impl
|
| 836 |
+
|
| 837 |
+
def register(cls, func=None):
|
| 838 |
+
"""generic_func.register(cls, func) -> func
|
| 839 |
+
|
| 840 |
+
Registers a new implementation for the given *cls* on a *generic_func*.
|
| 841 |
+
|
| 842 |
+
"""
|
| 843 |
+
nonlocal cache_token
|
| 844 |
+
if func is None:
|
| 845 |
+
if isinstance(cls, type):
|
| 846 |
+
return lambda f: register(cls, f)
|
| 847 |
+
ann = getattr(cls, '__annotations__', {})
|
| 848 |
+
if not ann:
|
| 849 |
+
raise TypeError(
|
| 850 |
+
f"Invalid first argument to `register()`: {cls!r}. "
|
| 851 |
+
f"Use either `@register(some_class)` or plain `@register` "
|
| 852 |
+
f"on an annotated function."
|
| 853 |
+
)
|
| 854 |
+
func = cls
|
| 855 |
+
|
| 856 |
+
# only import typing if annotation parsing is necessary
|
| 857 |
+
from typing import get_type_hints
|
| 858 |
+
argname, cls = next(iter(get_type_hints(func).items()))
|
| 859 |
+
if not isinstance(cls, type):
|
| 860 |
+
raise TypeError(
|
| 861 |
+
f"Invalid annotation for {argname!r}. "
|
| 862 |
+
f"{cls!r} is not a class."
|
| 863 |
+
)
|
| 864 |
+
registry[cls] = func
|
| 865 |
+
if cache_token is None and hasattr(cls, '__abstractmethods__'):
|
| 866 |
+
cache_token = get_cache_token()
|
| 867 |
+
dispatch_cache.clear()
|
| 868 |
+
return func
|
| 869 |
+
|
| 870 |
+
def wrapper(*args, **kw):
|
| 871 |
+
if not args:
|
| 872 |
+
raise TypeError(f'{funcname} requires at least '
|
| 873 |
+
'1 positional argument')
|
| 874 |
+
|
| 875 |
+
return dispatch(args[0].__class__)(*args, **kw)
|
| 876 |
+
|
| 877 |
+
funcname = getattr(func, '__name__', 'singledispatch function')
|
| 878 |
+
registry[object] = func
|
| 879 |
+
wrapper.register = register
|
| 880 |
+
wrapper.dispatch = dispatch
|
| 881 |
+
wrapper.registry = types.MappingProxyType(registry)
|
| 882 |
+
wrapper._clear_cache = dispatch_cache.clear
|
| 883 |
+
update_wrapper(wrapper, func)
|
| 884 |
+
return wrapper
|
| 885 |
+
|
| 886 |
+
|
| 887 |
+
# Descriptor version
|
| 888 |
+
class singledispatchmethod:
|
| 889 |
+
"""Single-dispatch generic method descriptor.
|
| 890 |
+
|
| 891 |
+
Supports wrapping existing descriptors and handles non-descriptor
|
| 892 |
+
callables as instance methods.
|
| 893 |
+
"""
|
| 894 |
+
|
| 895 |
+
def __init__(self, func):
|
| 896 |
+
if not callable(func) and not hasattr(func, "__get__"):
|
| 897 |
+
raise TypeError(f"{func!r} is not callable or a descriptor")
|
| 898 |
+
|
| 899 |
+
self.dispatcher = singledispatch(func)
|
| 900 |
+
self.func = func
|
| 901 |
+
|
| 902 |
+
def register(self, cls, method=None):
|
| 903 |
+
"""generic_method.register(cls, func) -> func
|
| 904 |
+
|
| 905 |
+
Registers a new implementation for the given *cls* on a *generic_method*.
|
| 906 |
+
"""
|
| 907 |
+
return self.dispatcher.register(cls, func=method)
|
| 908 |
+
|
| 909 |
+
def __get__(self, obj, cls=None):
|
| 910 |
+
def _method(*args, **kwargs):
|
| 911 |
+
method = self.dispatcher.dispatch(args[0].__class__)
|
| 912 |
+
return method.__get__(obj, cls)(*args, **kwargs)
|
| 913 |
+
|
| 914 |
+
_method.__isabstractmethod__ = self.__isabstractmethod__
|
| 915 |
+
_method.register = self.register
|
| 916 |
+
update_wrapper(_method, self.func)
|
| 917 |
+
return _method
|
| 918 |
+
|
| 919 |
+
@property
|
| 920 |
+
def __isabstractmethod__(self):
|
| 921 |
+
return getattr(self.func, '__isabstractmethod__', False)
|
| 922 |
+
|
| 923 |
+
|
| 924 |
+
################################################################################
|
| 925 |
+
### cached_property() - computed once per instance, cached as attribute
|
| 926 |
+
################################################################################
|
| 927 |
+
|
| 928 |
+
_NOT_FOUND = object()
|
| 929 |
+
|
| 930 |
+
|
| 931 |
+
class cached_property:
|
| 932 |
+
def __init__(self, func):
|
| 933 |
+
self.func = func
|
| 934 |
+
self.attrname = None
|
| 935 |
+
self.__doc__ = func.__doc__
|
| 936 |
+
self.lock = RLock()
|
| 937 |
+
|
| 938 |
+
def __set_name__(self, owner, name):
|
| 939 |
+
if self.attrname is None:
|
| 940 |
+
self.attrname = name
|
| 941 |
+
elif name != self.attrname:
|
| 942 |
+
raise TypeError(
|
| 943 |
+
"Cannot assign the same cached_property to two different names "
|
| 944 |
+
f"({self.attrname!r} and {name!r})."
|
| 945 |
+
)
|
| 946 |
+
|
| 947 |
+
def __get__(self, instance, owner=None):
|
| 948 |
+
if instance is None:
|
| 949 |
+
return self
|
| 950 |
+
if self.attrname is None:
|
| 951 |
+
raise TypeError(
|
| 952 |
+
"Cannot use cached_property instance without calling __set_name__ on it.")
|
| 953 |
+
try:
|
| 954 |
+
cache = instance.__dict__
|
| 955 |
+
except AttributeError: # not all objects have __dict__ (e.g. class defines slots)
|
| 956 |
+
msg = (
|
| 957 |
+
f"No '__dict__' attribute on {type(instance).__name__!r} "
|
| 958 |
+
f"instance to cache {self.attrname!r} property."
|
| 959 |
+
)
|
| 960 |
+
raise TypeError(msg) from None
|
| 961 |
+
val = cache.get(self.attrname, _NOT_FOUND)
|
| 962 |
+
if val is _NOT_FOUND:
|
| 963 |
+
with self.lock:
|
| 964 |
+
# check if another thread filled cache while we awaited lock
|
| 965 |
+
val = cache.get(self.attrname, _NOT_FOUND)
|
| 966 |
+
if val is _NOT_FOUND:
|
| 967 |
+
val = self.func(instance)
|
| 968 |
+
try:
|
| 969 |
+
cache[self.attrname] = val
|
| 970 |
+
except TypeError:
|
| 971 |
+
msg = (
|
| 972 |
+
f"The '__dict__' attribute on {type(instance).__name__!r} instance "
|
| 973 |
+
f"does not support item assignment for caching {self.attrname!r} property."
|
| 974 |
+
)
|
| 975 |
+
raise TypeError(msg) from None
|
| 976 |
+
return val
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/getpass.py
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Utilities to get a password and/or the current user name.
|
| 2 |
+
|
| 3 |
+
getpass(prompt[, stream]) - Prompt for a password, with echo turned off.
|
| 4 |
+
getuser() - Get the user name from the environment or password database.
|
| 5 |
+
|
| 6 |
+
GetPassWarning - This UserWarning is issued when getpass() cannot prevent
|
| 7 |
+
echoing of the password contents while reading.
|
| 8 |
+
|
| 9 |
+
On Windows, the msvcrt module will be used.
|
| 10 |
+
|
| 11 |
+
"""
|
| 12 |
+
|
| 13 |
+
# Authors: Piers Lauder (original)
|
| 14 |
+
# Guido van Rossum (Windows support and cleanup)
|
| 15 |
+
# Gregory P. Smith (tty support & GetPassWarning)
|
| 16 |
+
|
| 17 |
+
import contextlib
|
| 18 |
+
import io
|
| 19 |
+
import os
|
| 20 |
+
import sys
|
| 21 |
+
import warnings
|
| 22 |
+
|
| 23 |
+
__all__ = ["getpass","getuser","GetPassWarning"]
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
class GetPassWarning(UserWarning): pass
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def unix_getpass(prompt='Password: ', stream=None):
|
| 30 |
+
"""Prompt for a password, with echo turned off.
|
| 31 |
+
|
| 32 |
+
Args:
|
| 33 |
+
prompt: Written on stream to ask for the input. Default: 'Password: '
|
| 34 |
+
stream: A writable file object to display the prompt. Defaults to
|
| 35 |
+
the tty. If no tty is available defaults to sys.stderr.
|
| 36 |
+
Returns:
|
| 37 |
+
The seKr3t input.
|
| 38 |
+
Raises:
|
| 39 |
+
EOFError: If our input tty or stdin was closed.
|
| 40 |
+
GetPassWarning: When we were unable to turn echo off on the input.
|
| 41 |
+
|
| 42 |
+
Always restores terminal settings before returning.
|
| 43 |
+
"""
|
| 44 |
+
passwd = None
|
| 45 |
+
with contextlib.ExitStack() as stack:
|
| 46 |
+
try:
|
| 47 |
+
# Always try reading and writing directly on the tty first.
|
| 48 |
+
fd = os.open('/dev/tty', os.O_RDWR|os.O_NOCTTY)
|
| 49 |
+
tty = io.FileIO(fd, 'w+')
|
| 50 |
+
stack.enter_context(tty)
|
| 51 |
+
input = io.TextIOWrapper(tty)
|
| 52 |
+
stack.enter_context(input)
|
| 53 |
+
if not stream:
|
| 54 |
+
stream = input
|
| 55 |
+
except OSError as e:
|
| 56 |
+
# If that fails, see if stdin can be controlled.
|
| 57 |
+
stack.close()
|
| 58 |
+
try:
|
| 59 |
+
fd = sys.stdin.fileno()
|
| 60 |
+
except (AttributeError, ValueError):
|
| 61 |
+
fd = None
|
| 62 |
+
passwd = fallback_getpass(prompt, stream)
|
| 63 |
+
input = sys.stdin
|
| 64 |
+
if not stream:
|
| 65 |
+
stream = sys.stderr
|
| 66 |
+
|
| 67 |
+
if fd is not None:
|
| 68 |
+
try:
|
| 69 |
+
old = termios.tcgetattr(fd) # a copy to save
|
| 70 |
+
new = old[:]
|
| 71 |
+
new[3] &= ~termios.ECHO # 3 == 'lflags'
|
| 72 |
+
tcsetattr_flags = termios.TCSAFLUSH
|
| 73 |
+
if hasattr(termios, 'TCSASOFT'):
|
| 74 |
+
tcsetattr_flags |= termios.TCSASOFT
|
| 75 |
+
try:
|
| 76 |
+
termios.tcsetattr(fd, tcsetattr_flags, new)
|
| 77 |
+
passwd = _raw_input(prompt, stream, input=input)
|
| 78 |
+
finally:
|
| 79 |
+
termios.tcsetattr(fd, tcsetattr_flags, old)
|
| 80 |
+
stream.flush() # issue7208
|
| 81 |
+
except termios.error:
|
| 82 |
+
if passwd is not None:
|
| 83 |
+
# _raw_input succeeded. The final tcsetattr failed. Reraise
|
| 84 |
+
# instead of leaving the terminal in an unknown state.
|
| 85 |
+
raise
|
| 86 |
+
# We can't control the tty or stdin. Give up and use normal IO.
|
| 87 |
+
# fallback_getpass() raises an appropriate warning.
|
| 88 |
+
if stream is not input:
|
| 89 |
+
# clean up unused file objects before blocking
|
| 90 |
+
stack.close()
|
| 91 |
+
passwd = fallback_getpass(prompt, stream)
|
| 92 |
+
|
| 93 |
+
stream.write('\n')
|
| 94 |
+
return passwd
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
def win_getpass(prompt='Password: ', stream=None):
|
| 98 |
+
"""Prompt for password with echo off, using Windows getch()."""
|
| 99 |
+
if sys.stdin is not sys.__stdin__:
|
| 100 |
+
return fallback_getpass(prompt, stream)
|
| 101 |
+
|
| 102 |
+
for c in prompt:
|
| 103 |
+
msvcrt.putwch(c)
|
| 104 |
+
pw = ""
|
| 105 |
+
while 1:
|
| 106 |
+
c = msvcrt.getwch()
|
| 107 |
+
if c == '\r' or c == '\n':
|
| 108 |
+
break
|
| 109 |
+
if c == '\003':
|
| 110 |
+
raise KeyboardInterrupt
|
| 111 |
+
if c == '\b':
|
| 112 |
+
pw = pw[:-1]
|
| 113 |
+
else:
|
| 114 |
+
pw = pw + c
|
| 115 |
+
msvcrt.putwch('\r')
|
| 116 |
+
msvcrt.putwch('\n')
|
| 117 |
+
return pw
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
def fallback_getpass(prompt='Password: ', stream=None):
|
| 121 |
+
warnings.warn("Can not control echo on the terminal.", GetPassWarning,
|
| 122 |
+
stacklevel=2)
|
| 123 |
+
if not stream:
|
| 124 |
+
stream = sys.stderr
|
| 125 |
+
print("Warning: Password input may be echoed.", file=stream)
|
| 126 |
+
return _raw_input(prompt, stream)
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
def _raw_input(prompt="", stream=None, input=None):
|
| 130 |
+
# This doesn't save the string in the GNU readline history.
|
| 131 |
+
if not stream:
|
| 132 |
+
stream = sys.stderr
|
| 133 |
+
if not input:
|
| 134 |
+
input = sys.stdin
|
| 135 |
+
prompt = str(prompt)
|
| 136 |
+
if prompt:
|
| 137 |
+
try:
|
| 138 |
+
stream.write(prompt)
|
| 139 |
+
except UnicodeEncodeError:
|
| 140 |
+
# Use replace error handler to get as much as possible printed.
|
| 141 |
+
prompt = prompt.encode(stream.encoding, 'replace')
|
| 142 |
+
prompt = prompt.decode(stream.encoding)
|
| 143 |
+
stream.write(prompt)
|
| 144 |
+
stream.flush()
|
| 145 |
+
# NOTE: The Python C API calls flockfile() (and unlock) during readline.
|
| 146 |
+
line = input.readline()
|
| 147 |
+
if not line:
|
| 148 |
+
raise EOFError
|
| 149 |
+
if line[-1] == '\n':
|
| 150 |
+
line = line[:-1]
|
| 151 |
+
return line
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
def getuser():
|
| 155 |
+
"""Get the username from the environment or password database.
|
| 156 |
+
|
| 157 |
+
First try various environment variables, then the password
|
| 158 |
+
database. This works on Windows as long as USERNAME is set.
|
| 159 |
+
|
| 160 |
+
"""
|
| 161 |
+
|
| 162 |
+
for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
|
| 163 |
+
user = os.environ.get(name)
|
| 164 |
+
if user:
|
| 165 |
+
return user
|
| 166 |
+
|
| 167 |
+
# If this fails, the exception will "explain" why
|
| 168 |
+
import pwd
|
| 169 |
+
return pwd.getpwuid(os.getuid())[0]
|
| 170 |
+
|
| 171 |
+
# Bind the name getpass to the appropriate function
|
| 172 |
+
try:
|
| 173 |
+
import termios
|
| 174 |
+
# it's possible there is an incompatible termios from the
|
| 175 |
+
# McMillan Installer, make sure we have a UNIX-compatible termios
|
| 176 |
+
termios.tcgetattr, termios.tcsetattr
|
| 177 |
+
except (ImportError, AttributeError):
|
| 178 |
+
try:
|
| 179 |
+
import msvcrt
|
| 180 |
+
except ImportError:
|
| 181 |
+
getpass = fallback_getpass
|
| 182 |
+
else:
|
| 183 |
+
getpass = win_getpass
|
| 184 |
+
else:
|
| 185 |
+
getpass = unix_getpass
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/gettext.py
ADDED
|
@@ -0,0 +1,782 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Internationalization and localization support.
|
| 2 |
+
|
| 3 |
+
This module provides internationalization (I18N) and localization (L10N)
|
| 4 |
+
support for your Python programs by providing an interface to the GNU gettext
|
| 5 |
+
message catalog library.
|
| 6 |
+
|
| 7 |
+
I18N refers to the operation by which a program is made aware of multiple
|
| 8 |
+
languages. L10N refers to the adaptation of your program, once
|
| 9 |
+
internationalized, to the local language and cultural habits.
|
| 10 |
+
|
| 11 |
+
"""
|
| 12 |
+
|
| 13 |
+
# This module represents the integration of work, contributions, feedback, and
|
| 14 |
+
# suggestions from the following people:
|
| 15 |
+
#
|
| 16 |
+
# Martin von Loewis, who wrote the initial implementation of the underlying
|
| 17 |
+
# C-based libintlmodule (later renamed _gettext), along with a skeletal
|
| 18 |
+
# gettext.py implementation.
|
| 19 |
+
#
|
| 20 |
+
# Peter Funk, who wrote fintl.py, a fairly complete wrapper around intlmodule,
|
| 21 |
+
# which also included a pure-Python implementation to read .mo files if
|
| 22 |
+
# intlmodule wasn't available.
|
| 23 |
+
#
|
| 24 |
+
# James Henstridge, who also wrote a gettext.py module, which has some
|
| 25 |
+
# interesting, but currently unsupported experimental features: the notion of
|
| 26 |
+
# a Catalog class and instances, and the ability to add to a catalog file via
|
| 27 |
+
# a Python API.
|
| 28 |
+
#
|
| 29 |
+
# Barry Warsaw integrated these modules, wrote the .install() API and code,
|
| 30 |
+
# and conformed all C and Python code to Python's coding standards.
|
| 31 |
+
#
|
| 32 |
+
# Francois Pinard and Marc-Andre Lemburg also contributed valuably to this
|
| 33 |
+
# module.
|
| 34 |
+
#
|
| 35 |
+
# J. David Ibanez implemented plural forms. Bruno Haible fixed some bugs.
|
| 36 |
+
#
|
| 37 |
+
# TODO:
|
| 38 |
+
# - Lazy loading of .mo files. Currently the entire catalog is loaded into
|
| 39 |
+
# memory, but that's probably bad for large translated programs. Instead,
|
| 40 |
+
# the lexical sort of original strings in GNU .mo files should be exploited
|
| 41 |
+
# to do binary searches and lazy initializations. Or you might want to use
|
| 42 |
+
# the undocumented double-hash algorithm for .mo files with hash tables, but
|
| 43 |
+
# you'll need to study the GNU gettext code to do this.
|
| 44 |
+
#
|
| 45 |
+
# - Support Solaris .mo file formats. Unfortunately, we've been unable to
|
| 46 |
+
# find this format documented anywhere.
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
import locale
|
| 50 |
+
import os
|
| 51 |
+
import re
|
| 52 |
+
import sys
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
__all__ = ['NullTranslations', 'GNUTranslations', 'Catalog',
|
| 56 |
+
'find', 'translation', 'install', 'textdomain', 'bindtextdomain',
|
| 57 |
+
'bind_textdomain_codeset',
|
| 58 |
+
'dgettext', 'dngettext', 'gettext', 'lgettext', 'ldgettext',
|
| 59 |
+
'ldngettext', 'lngettext', 'ngettext',
|
| 60 |
+
'pgettext', 'dpgettext', 'npgettext', 'dnpgettext',
|
| 61 |
+
]
|
| 62 |
+
|
| 63 |
+
_default_localedir = os.path.join(sys.base_prefix, 'share', 'locale')
|
| 64 |
+
|
| 65 |
+
# Expression parsing for plural form selection.
|
| 66 |
+
#
|
| 67 |
+
# The gettext library supports a small subset of C syntax. The only
|
| 68 |
+
# incompatible difference is that integer literals starting with zero are
|
| 69 |
+
# decimal.
|
| 70 |
+
#
|
| 71 |
+
# https://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms
|
| 72 |
+
# http://git.savannah.gnu.org/cgit/gettext.git/tree/gettext-runtime/intl/plural.y
|
| 73 |
+
|
| 74 |
+
_token_pattern = re.compile(r"""
|
| 75 |
+
(?P<WHITESPACES>[ \t]+) | # spaces and horizontal tabs
|
| 76 |
+
(?P<NUMBER>[0-9]+\b) | # decimal integer
|
| 77 |
+
(?P<NAME>n\b) | # only n is allowed
|
| 78 |
+
(?P<PARENTHESIS>[()]) |
|
| 79 |
+
(?P<OPERATOR>[-*/%+?:]|[><!]=?|==|&&|\|\|) | # !, *, /, %, +, -, <, >,
|
| 80 |
+
# <=, >=, ==, !=, &&, ||,
|
| 81 |
+
# ? :
|
| 82 |
+
# unary and bitwise ops
|
| 83 |
+
# not allowed
|
| 84 |
+
(?P<INVALID>\w+|.) # invalid token
|
| 85 |
+
""", re.VERBOSE|re.DOTALL)
|
| 86 |
+
|
| 87 |
+
def _tokenize(plural):
|
| 88 |
+
for mo in re.finditer(_token_pattern, plural):
|
| 89 |
+
kind = mo.lastgroup
|
| 90 |
+
if kind == 'WHITESPACES':
|
| 91 |
+
continue
|
| 92 |
+
value = mo.group(kind)
|
| 93 |
+
if kind == 'INVALID':
|
| 94 |
+
raise ValueError('invalid token in plural form: %s' % value)
|
| 95 |
+
yield value
|
| 96 |
+
yield ''
|
| 97 |
+
|
| 98 |
+
def _error(value):
|
| 99 |
+
if value:
|
| 100 |
+
return ValueError('unexpected token in plural form: %s' % value)
|
| 101 |
+
else:
|
| 102 |
+
return ValueError('unexpected end of plural form')
|
| 103 |
+
|
| 104 |
+
_binary_ops = (
|
| 105 |
+
('||',),
|
| 106 |
+
('&&',),
|
| 107 |
+
('==', '!='),
|
| 108 |
+
('<', '>', '<=', '>='),
|
| 109 |
+
('+', '-'),
|
| 110 |
+
('*', '/', '%'),
|
| 111 |
+
)
|
| 112 |
+
_binary_ops = {op: i for i, ops in enumerate(_binary_ops, 1) for op in ops}
|
| 113 |
+
_c2py_ops = {'||': 'or', '&&': 'and', '/': '//'}
|
| 114 |
+
|
| 115 |
+
def _parse(tokens, priority=-1):
|
| 116 |
+
result = ''
|
| 117 |
+
nexttok = next(tokens)
|
| 118 |
+
while nexttok == '!':
|
| 119 |
+
result += 'not '
|
| 120 |
+
nexttok = next(tokens)
|
| 121 |
+
|
| 122 |
+
if nexttok == '(':
|
| 123 |
+
sub, nexttok = _parse(tokens)
|
| 124 |
+
result = '%s(%s)' % (result, sub)
|
| 125 |
+
if nexttok != ')':
|
| 126 |
+
raise ValueError('unbalanced parenthesis in plural form')
|
| 127 |
+
elif nexttok == 'n':
|
| 128 |
+
result = '%s%s' % (result, nexttok)
|
| 129 |
+
else:
|
| 130 |
+
try:
|
| 131 |
+
value = int(nexttok, 10)
|
| 132 |
+
except ValueError:
|
| 133 |
+
raise _error(nexttok) from None
|
| 134 |
+
result = '%s%d' % (result, value)
|
| 135 |
+
nexttok = next(tokens)
|
| 136 |
+
|
| 137 |
+
j = 100
|
| 138 |
+
while nexttok in _binary_ops:
|
| 139 |
+
i = _binary_ops[nexttok]
|
| 140 |
+
if i < priority:
|
| 141 |
+
break
|
| 142 |
+
# Break chained comparisons
|
| 143 |
+
if i in (3, 4) and j in (3, 4): # '==', '!=', '<', '>', '<=', '>='
|
| 144 |
+
result = '(%s)' % result
|
| 145 |
+
# Replace some C operators by their Python equivalents
|
| 146 |
+
op = _c2py_ops.get(nexttok, nexttok)
|
| 147 |
+
right, nexttok = _parse(tokens, i + 1)
|
| 148 |
+
result = '%s %s %s' % (result, op, right)
|
| 149 |
+
j = i
|
| 150 |
+
if j == priority == 4: # '<', '>', '<=', '>='
|
| 151 |
+
result = '(%s)' % result
|
| 152 |
+
|
| 153 |
+
if nexttok == '?' and priority <= 0:
|
| 154 |
+
if_true, nexttok = _parse(tokens, 0)
|
| 155 |
+
if nexttok != ':':
|
| 156 |
+
raise _error(nexttok)
|
| 157 |
+
if_false, nexttok = _parse(tokens)
|
| 158 |
+
result = '%s if %s else %s' % (if_true, result, if_false)
|
| 159 |
+
if priority == 0:
|
| 160 |
+
result = '(%s)' % result
|
| 161 |
+
|
| 162 |
+
return result, nexttok
|
| 163 |
+
|
| 164 |
+
def _as_int(n):
|
| 165 |
+
try:
|
| 166 |
+
i = round(n)
|
| 167 |
+
except TypeError:
|
| 168 |
+
raise TypeError('Plural value must be an integer, got %s' %
|
| 169 |
+
(n.__class__.__name__,)) from None
|
| 170 |
+
import warnings
|
| 171 |
+
warnings.warn('Plural value must be an integer, got %s' %
|
| 172 |
+
(n.__class__.__name__,),
|
| 173 |
+
DeprecationWarning, 4)
|
| 174 |
+
return n
|
| 175 |
+
|
| 176 |
+
def c2py(plural):
|
| 177 |
+
"""Gets a C expression as used in PO files for plural forms and returns a
|
| 178 |
+
Python function that implements an equivalent expression.
|
| 179 |
+
"""
|
| 180 |
+
|
| 181 |
+
if len(plural) > 1000:
|
| 182 |
+
raise ValueError('plural form expression is too long')
|
| 183 |
+
try:
|
| 184 |
+
result, nexttok = _parse(_tokenize(plural))
|
| 185 |
+
if nexttok:
|
| 186 |
+
raise _error(nexttok)
|
| 187 |
+
|
| 188 |
+
depth = 0
|
| 189 |
+
for c in result:
|
| 190 |
+
if c == '(':
|
| 191 |
+
depth += 1
|
| 192 |
+
if depth > 20:
|
| 193 |
+
# Python compiler limit is about 90.
|
| 194 |
+
# The most complex example has 2.
|
| 195 |
+
raise ValueError('plural form expression is too complex')
|
| 196 |
+
elif c == ')':
|
| 197 |
+
depth -= 1
|
| 198 |
+
|
| 199 |
+
ns = {'_as_int': _as_int}
|
| 200 |
+
exec('''if True:
|
| 201 |
+
def func(n):
|
| 202 |
+
if not isinstance(n, int):
|
| 203 |
+
n = _as_int(n)
|
| 204 |
+
return int(%s)
|
| 205 |
+
''' % result, ns)
|
| 206 |
+
return ns['func']
|
| 207 |
+
except RecursionError:
|
| 208 |
+
# Recursion error can be raised in _parse() or exec().
|
| 209 |
+
raise ValueError('plural form expression is too complex')
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
def _expand_lang(loc):
|
| 213 |
+
loc = locale.normalize(loc)
|
| 214 |
+
COMPONENT_CODESET = 1 << 0
|
| 215 |
+
COMPONENT_TERRITORY = 1 << 1
|
| 216 |
+
COMPONENT_MODIFIER = 1 << 2
|
| 217 |
+
# split up the locale into its base components
|
| 218 |
+
mask = 0
|
| 219 |
+
pos = loc.find('@')
|
| 220 |
+
if pos >= 0:
|
| 221 |
+
modifier = loc[pos:]
|
| 222 |
+
loc = loc[:pos]
|
| 223 |
+
mask |= COMPONENT_MODIFIER
|
| 224 |
+
else:
|
| 225 |
+
modifier = ''
|
| 226 |
+
pos = loc.find('.')
|
| 227 |
+
if pos >= 0:
|
| 228 |
+
codeset = loc[pos:]
|
| 229 |
+
loc = loc[:pos]
|
| 230 |
+
mask |= COMPONENT_CODESET
|
| 231 |
+
else:
|
| 232 |
+
codeset = ''
|
| 233 |
+
pos = loc.find('_')
|
| 234 |
+
if pos >= 0:
|
| 235 |
+
territory = loc[pos:]
|
| 236 |
+
loc = loc[:pos]
|
| 237 |
+
mask |= COMPONENT_TERRITORY
|
| 238 |
+
else:
|
| 239 |
+
territory = ''
|
| 240 |
+
language = loc
|
| 241 |
+
ret = []
|
| 242 |
+
for i in range(mask+1):
|
| 243 |
+
if not (i & ~mask): # if all components for this combo exist ...
|
| 244 |
+
val = language
|
| 245 |
+
if i & COMPONENT_TERRITORY: val += territory
|
| 246 |
+
if i & COMPONENT_CODESET: val += codeset
|
| 247 |
+
if i & COMPONENT_MODIFIER: val += modifier
|
| 248 |
+
ret.append(val)
|
| 249 |
+
ret.reverse()
|
| 250 |
+
return ret
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
|
| 254 |
+
class NullTranslations:
|
| 255 |
+
def __init__(self, fp=None):
|
| 256 |
+
self._info = {}
|
| 257 |
+
self._charset = None
|
| 258 |
+
self._output_charset = None
|
| 259 |
+
self._fallback = None
|
| 260 |
+
if fp is not None:
|
| 261 |
+
self._parse(fp)
|
| 262 |
+
|
| 263 |
+
def _parse(self, fp):
|
| 264 |
+
pass
|
| 265 |
+
|
| 266 |
+
def add_fallback(self, fallback):
|
| 267 |
+
if self._fallback:
|
| 268 |
+
self._fallback.add_fallback(fallback)
|
| 269 |
+
else:
|
| 270 |
+
self._fallback = fallback
|
| 271 |
+
|
| 272 |
+
def gettext(self, message):
|
| 273 |
+
if self._fallback:
|
| 274 |
+
return self._fallback.gettext(message)
|
| 275 |
+
return message
|
| 276 |
+
|
| 277 |
+
def lgettext(self, message):
|
| 278 |
+
import warnings
|
| 279 |
+
warnings.warn('lgettext() is deprecated, use gettext() instead',
|
| 280 |
+
DeprecationWarning, 2)
|
| 281 |
+
if self._fallback:
|
| 282 |
+
with warnings.catch_warnings():
|
| 283 |
+
warnings.filterwarnings('ignore', r'.*\blgettext\b.*',
|
| 284 |
+
DeprecationWarning)
|
| 285 |
+
return self._fallback.lgettext(message)
|
| 286 |
+
if self._output_charset:
|
| 287 |
+
return message.encode(self._output_charset)
|
| 288 |
+
return message.encode(locale.getpreferredencoding())
|
| 289 |
+
|
| 290 |
+
def ngettext(self, msgid1, msgid2, n):
|
| 291 |
+
if self._fallback:
|
| 292 |
+
return self._fallback.ngettext(msgid1, msgid2, n)
|
| 293 |
+
if n == 1:
|
| 294 |
+
return msgid1
|
| 295 |
+
else:
|
| 296 |
+
return msgid2
|
| 297 |
+
|
| 298 |
+
def lngettext(self, msgid1, msgid2, n):
|
| 299 |
+
import warnings
|
| 300 |
+
warnings.warn('lngettext() is deprecated, use ngettext() instead',
|
| 301 |
+
DeprecationWarning, 2)
|
| 302 |
+
if self._fallback:
|
| 303 |
+
with warnings.catch_warnings():
|
| 304 |
+
warnings.filterwarnings('ignore', r'.*\blngettext\b.*',
|
| 305 |
+
DeprecationWarning)
|
| 306 |
+
return self._fallback.lngettext(msgid1, msgid2, n)
|
| 307 |
+
if n == 1:
|
| 308 |
+
tmsg = msgid1
|
| 309 |
+
else:
|
| 310 |
+
tmsg = msgid2
|
| 311 |
+
if self._output_charset:
|
| 312 |
+
return tmsg.encode(self._output_charset)
|
| 313 |
+
return tmsg.encode(locale.getpreferredencoding())
|
| 314 |
+
|
| 315 |
+
def pgettext(self, context, message):
|
| 316 |
+
if self._fallback:
|
| 317 |
+
return self._fallback.pgettext(context, message)
|
| 318 |
+
return message
|
| 319 |
+
|
| 320 |
+
def npgettext(self, context, msgid1, msgid2, n):
|
| 321 |
+
if self._fallback:
|
| 322 |
+
return self._fallback.npgettext(context, msgid1, msgid2, n)
|
| 323 |
+
if n == 1:
|
| 324 |
+
return msgid1
|
| 325 |
+
else:
|
| 326 |
+
return msgid2
|
| 327 |
+
|
| 328 |
+
def info(self):
|
| 329 |
+
return self._info
|
| 330 |
+
|
| 331 |
+
def charset(self):
|
| 332 |
+
return self._charset
|
| 333 |
+
|
| 334 |
+
def output_charset(self):
|
| 335 |
+
import warnings
|
| 336 |
+
warnings.warn('output_charset() is deprecated',
|
| 337 |
+
DeprecationWarning, 2)
|
| 338 |
+
return self._output_charset
|
| 339 |
+
|
| 340 |
+
def set_output_charset(self, charset):
|
| 341 |
+
import warnings
|
| 342 |
+
warnings.warn('set_output_charset() is deprecated',
|
| 343 |
+
DeprecationWarning, 2)
|
| 344 |
+
self._output_charset = charset
|
| 345 |
+
|
| 346 |
+
def install(self, names=None):
|
| 347 |
+
import builtins
|
| 348 |
+
builtins.__dict__['_'] = self.gettext
|
| 349 |
+
if names is not None:
|
| 350 |
+
allowed = {'gettext', 'lgettext', 'lngettext',
|
| 351 |
+
'ngettext', 'npgettext', 'pgettext'}
|
| 352 |
+
for name in allowed & set(names):
|
| 353 |
+
builtins.__dict__[name] = getattr(self, name)
|
| 354 |
+
|
| 355 |
+
|
| 356 |
+
class GNUTranslations(NullTranslations):
|
| 357 |
+
# Magic number of .mo files
|
| 358 |
+
LE_MAGIC = 0x950412de
|
| 359 |
+
BE_MAGIC = 0xde120495
|
| 360 |
+
|
| 361 |
+
# The encoding of a msgctxt and a msgid in a .mo file is
|
| 362 |
+
# msgctxt + "\x04" + msgid (gettext version >= 0.15)
|
| 363 |
+
CONTEXT = "%s\x04%s"
|
| 364 |
+
|
| 365 |
+
# Acceptable .mo versions
|
| 366 |
+
VERSIONS = (0, 1)
|
| 367 |
+
|
| 368 |
+
def _get_versions(self, version):
|
| 369 |
+
"""Returns a tuple of major version, minor version"""
|
| 370 |
+
return (version >> 16, version & 0xffff)
|
| 371 |
+
|
| 372 |
+
def _parse(self, fp):
|
| 373 |
+
"""Override this method to support alternative .mo formats."""
|
| 374 |
+
# Delay struct import for speeding up gettext import when .mo files
|
| 375 |
+
# are not used.
|
| 376 |
+
from struct import unpack
|
| 377 |
+
filename = getattr(fp, 'name', '')
|
| 378 |
+
# Parse the .mo file header, which consists of 5 little endian 32
|
| 379 |
+
# bit words.
|
| 380 |
+
self._catalog = catalog = {}
|
| 381 |
+
self.plural = lambda n: int(n != 1) # germanic plural by default
|
| 382 |
+
buf = fp.read()
|
| 383 |
+
buflen = len(buf)
|
| 384 |
+
# Are we big endian or little endian?
|
| 385 |
+
magic = unpack('<I', buf[:4])[0]
|
| 386 |
+
if magic == self.LE_MAGIC:
|
| 387 |
+
version, msgcount, masteridx, transidx = unpack('<4I', buf[4:20])
|
| 388 |
+
ii = '<II'
|
| 389 |
+
elif magic == self.BE_MAGIC:
|
| 390 |
+
version, msgcount, masteridx, transidx = unpack('>4I', buf[4:20])
|
| 391 |
+
ii = '>II'
|
| 392 |
+
else:
|
| 393 |
+
raise OSError(0, 'Bad magic number', filename)
|
| 394 |
+
|
| 395 |
+
major_version, minor_version = self._get_versions(version)
|
| 396 |
+
|
| 397 |
+
if major_version not in self.VERSIONS:
|
| 398 |
+
raise OSError(0, 'Bad version number ' + str(major_version), filename)
|
| 399 |
+
|
| 400 |
+
# Now put all messages from the .mo file buffer into the catalog
|
| 401 |
+
# dictionary.
|
| 402 |
+
for i in range(0, msgcount):
|
| 403 |
+
mlen, moff = unpack(ii, buf[masteridx:masteridx+8])
|
| 404 |
+
mend = moff + mlen
|
| 405 |
+
tlen, toff = unpack(ii, buf[transidx:transidx+8])
|
| 406 |
+
tend = toff + tlen
|
| 407 |
+
if mend < buflen and tend < buflen:
|
| 408 |
+
msg = buf[moff:mend]
|
| 409 |
+
tmsg = buf[toff:tend]
|
| 410 |
+
else:
|
| 411 |
+
raise OSError(0, 'File is corrupt', filename)
|
| 412 |
+
# See if we're looking at GNU .mo conventions for metadata
|
| 413 |
+
if mlen == 0:
|
| 414 |
+
# Catalog description
|
| 415 |
+
lastk = None
|
| 416 |
+
for b_item in tmsg.split(b'\n'):
|
| 417 |
+
item = b_item.decode().strip()
|
| 418 |
+
if not item:
|
| 419 |
+
continue
|
| 420 |
+
# Skip over comment lines:
|
| 421 |
+
if item.startswith('#-#-#-#-#') and item.endswith('#-#-#-#-#'):
|
| 422 |
+
continue
|
| 423 |
+
k = v = None
|
| 424 |
+
if ':' in item:
|
| 425 |
+
k, v = item.split(':', 1)
|
| 426 |
+
k = k.strip().lower()
|
| 427 |
+
v = v.strip()
|
| 428 |
+
self._info[k] = v
|
| 429 |
+
lastk = k
|
| 430 |
+
elif lastk:
|
| 431 |
+
self._info[lastk] += '\n' + item
|
| 432 |
+
if k == 'content-type':
|
| 433 |
+
self._charset = v.split('charset=')[1]
|
| 434 |
+
elif k == 'plural-forms':
|
| 435 |
+
v = v.split(';')
|
| 436 |
+
plural = v[1].split('plural=')[1]
|
| 437 |
+
self.plural = c2py(plural)
|
| 438 |
+
# Note: we unconditionally convert both msgids and msgstrs to
|
| 439 |
+
# Unicode using the character encoding specified in the charset
|
| 440 |
+
# parameter of the Content-Type header. The gettext documentation
|
| 441 |
+
# strongly encourages msgids to be us-ascii, but some applications
|
| 442 |
+
# require alternative encodings (e.g. Zope's ZCML and ZPT). For
|
| 443 |
+
# traditional gettext applications, the msgid conversion will
|
| 444 |
+
# cause no problems since us-ascii should always be a subset of
|
| 445 |
+
# the charset encoding. We may want to fall back to 8-bit msgids
|
| 446 |
+
# if the Unicode conversion fails.
|
| 447 |
+
charset = self._charset or 'ascii'
|
| 448 |
+
if b'\x00' in msg:
|
| 449 |
+
# Plural forms
|
| 450 |
+
msgid1, msgid2 = msg.split(b'\x00')
|
| 451 |
+
tmsg = tmsg.split(b'\x00')
|
| 452 |
+
msgid1 = str(msgid1, charset)
|
| 453 |
+
for i, x in enumerate(tmsg):
|
| 454 |
+
catalog[(msgid1, i)] = str(x, charset)
|
| 455 |
+
else:
|
| 456 |
+
catalog[str(msg, charset)] = str(tmsg, charset)
|
| 457 |
+
# advance to next entry in the seek tables
|
| 458 |
+
masteridx += 8
|
| 459 |
+
transidx += 8
|
| 460 |
+
|
| 461 |
+
def lgettext(self, message):
|
| 462 |
+
import warnings
|
| 463 |
+
warnings.warn('lgettext() is deprecated, use gettext() instead',
|
| 464 |
+
DeprecationWarning, 2)
|
| 465 |
+
missing = object()
|
| 466 |
+
tmsg = self._catalog.get(message, missing)
|
| 467 |
+
if tmsg is missing:
|
| 468 |
+
if self._fallback:
|
| 469 |
+
return self._fallback.lgettext(message)
|
| 470 |
+
tmsg = message
|
| 471 |
+
if self._output_charset:
|
| 472 |
+
return tmsg.encode(self._output_charset)
|
| 473 |
+
return tmsg.encode(locale.getpreferredencoding())
|
| 474 |
+
|
| 475 |
+
def lngettext(self, msgid1, msgid2, n):
|
| 476 |
+
import warnings
|
| 477 |
+
warnings.warn('lngettext() is deprecated, use ngettext() instead',
|
| 478 |
+
DeprecationWarning, 2)
|
| 479 |
+
try:
|
| 480 |
+
tmsg = self._catalog[(msgid1, self.plural(n))]
|
| 481 |
+
except KeyError:
|
| 482 |
+
if self._fallback:
|
| 483 |
+
return self._fallback.lngettext(msgid1, msgid2, n)
|
| 484 |
+
if n == 1:
|
| 485 |
+
tmsg = msgid1
|
| 486 |
+
else:
|
| 487 |
+
tmsg = msgid2
|
| 488 |
+
if self._output_charset:
|
| 489 |
+
return tmsg.encode(self._output_charset)
|
| 490 |
+
return tmsg.encode(locale.getpreferredencoding())
|
| 491 |
+
|
| 492 |
+
def gettext(self, message):
|
| 493 |
+
missing = object()
|
| 494 |
+
tmsg = self._catalog.get(message, missing)
|
| 495 |
+
if tmsg is missing:
|
| 496 |
+
if self._fallback:
|
| 497 |
+
return self._fallback.gettext(message)
|
| 498 |
+
return message
|
| 499 |
+
return tmsg
|
| 500 |
+
|
| 501 |
+
def ngettext(self, msgid1, msgid2, n):
|
| 502 |
+
try:
|
| 503 |
+
tmsg = self._catalog[(msgid1, self.plural(n))]
|
| 504 |
+
except KeyError:
|
| 505 |
+
if self._fallback:
|
| 506 |
+
return self._fallback.ngettext(msgid1, msgid2, n)
|
| 507 |
+
if n == 1:
|
| 508 |
+
tmsg = msgid1
|
| 509 |
+
else:
|
| 510 |
+
tmsg = msgid2
|
| 511 |
+
return tmsg
|
| 512 |
+
|
| 513 |
+
def pgettext(self, context, message):
|
| 514 |
+
ctxt_msg_id = self.CONTEXT % (context, message)
|
| 515 |
+
missing = object()
|
| 516 |
+
tmsg = self._catalog.get(ctxt_msg_id, missing)
|
| 517 |
+
if tmsg is missing:
|
| 518 |
+
if self._fallback:
|
| 519 |
+
return self._fallback.pgettext(context, message)
|
| 520 |
+
return message
|
| 521 |
+
return tmsg
|
| 522 |
+
|
| 523 |
+
def npgettext(self, context, msgid1, msgid2, n):
|
| 524 |
+
ctxt_msg_id = self.CONTEXT % (context, msgid1)
|
| 525 |
+
try:
|
| 526 |
+
tmsg = self._catalog[ctxt_msg_id, self.plural(n)]
|
| 527 |
+
except KeyError:
|
| 528 |
+
if self._fallback:
|
| 529 |
+
return self._fallback.npgettext(context, msgid1, msgid2, n)
|
| 530 |
+
if n == 1:
|
| 531 |
+
tmsg = msgid1
|
| 532 |
+
else:
|
| 533 |
+
tmsg = msgid2
|
| 534 |
+
return tmsg
|
| 535 |
+
|
| 536 |
+
|
| 537 |
+
# Locate a .mo file using the gettext strategy
|
| 538 |
+
def find(domain, localedir=None, languages=None, all=False):
|
| 539 |
+
# Get some reasonable defaults for arguments that were not supplied
|
| 540 |
+
if localedir is None:
|
| 541 |
+
localedir = _default_localedir
|
| 542 |
+
if languages is None:
|
| 543 |
+
languages = []
|
| 544 |
+
for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
|
| 545 |
+
val = os.environ.get(envar)
|
| 546 |
+
if val:
|
| 547 |
+
languages = val.split(':')
|
| 548 |
+
break
|
| 549 |
+
if 'C' not in languages:
|
| 550 |
+
languages.append('C')
|
| 551 |
+
# now normalize and expand the languages
|
| 552 |
+
nelangs = []
|
| 553 |
+
for lang in languages:
|
| 554 |
+
for nelang in _expand_lang(lang):
|
| 555 |
+
if nelang not in nelangs:
|
| 556 |
+
nelangs.append(nelang)
|
| 557 |
+
# select a language
|
| 558 |
+
if all:
|
| 559 |
+
result = []
|
| 560 |
+
else:
|
| 561 |
+
result = None
|
| 562 |
+
for lang in nelangs:
|
| 563 |
+
if lang == 'C':
|
| 564 |
+
break
|
| 565 |
+
mofile = os.path.join(localedir, lang, 'LC_MESSAGES', '%s.mo' % domain)
|
| 566 |
+
if os.path.exists(mofile):
|
| 567 |
+
if all:
|
| 568 |
+
result.append(mofile)
|
| 569 |
+
else:
|
| 570 |
+
return mofile
|
| 571 |
+
return result
|
| 572 |
+
|
| 573 |
+
|
| 574 |
+
|
| 575 |
+
# a mapping between absolute .mo file path and Translation object
|
| 576 |
+
_translations = {}
|
| 577 |
+
_unspecified = ['unspecified']
|
| 578 |
+
|
| 579 |
+
def translation(domain, localedir=None, languages=None,
|
| 580 |
+
class_=None, fallback=False, codeset=_unspecified):
|
| 581 |
+
if class_ is None:
|
| 582 |
+
class_ = GNUTranslations
|
| 583 |
+
mofiles = find(domain, localedir, languages, all=True)
|
| 584 |
+
if not mofiles:
|
| 585 |
+
if fallback:
|
| 586 |
+
return NullTranslations()
|
| 587 |
+
from errno import ENOENT
|
| 588 |
+
raise FileNotFoundError(ENOENT,
|
| 589 |
+
'No translation file found for domain', domain)
|
| 590 |
+
# Avoid opening, reading, and parsing the .mo file after it's been done
|
| 591 |
+
# once.
|
| 592 |
+
result = None
|
| 593 |
+
for mofile in mofiles:
|
| 594 |
+
key = (class_, os.path.abspath(mofile))
|
| 595 |
+
t = _translations.get(key)
|
| 596 |
+
if t is None:
|
| 597 |
+
with open(mofile, 'rb') as fp:
|
| 598 |
+
t = _translations.setdefault(key, class_(fp))
|
| 599 |
+
# Copy the translation object to allow setting fallbacks and
|
| 600 |
+
# output charset. All other instance data is shared with the
|
| 601 |
+
# cached object.
|
| 602 |
+
# Delay copy import for speeding up gettext import when .mo files
|
| 603 |
+
# are not used.
|
| 604 |
+
import copy
|
| 605 |
+
t = copy.copy(t)
|
| 606 |
+
if codeset is not _unspecified:
|
| 607 |
+
import warnings
|
| 608 |
+
warnings.warn('parameter codeset is deprecated',
|
| 609 |
+
DeprecationWarning, 2)
|
| 610 |
+
if codeset:
|
| 611 |
+
with warnings.catch_warnings():
|
| 612 |
+
warnings.filterwarnings('ignore', r'.*\bset_output_charset\b.*',
|
| 613 |
+
DeprecationWarning)
|
| 614 |
+
t.set_output_charset(codeset)
|
| 615 |
+
if result is None:
|
| 616 |
+
result = t
|
| 617 |
+
else:
|
| 618 |
+
result.add_fallback(t)
|
| 619 |
+
return result
|
| 620 |
+
|
| 621 |
+
|
| 622 |
+
def install(domain, localedir=None, codeset=_unspecified, names=None):
|
| 623 |
+
t = translation(domain, localedir, fallback=True, codeset=codeset)
|
| 624 |
+
t.install(names)
|
| 625 |
+
|
| 626 |
+
|
| 627 |
+
|
| 628 |
+
# a mapping b/w domains and locale directories
|
| 629 |
+
_localedirs = {}
|
| 630 |
+
# a mapping b/w domains and codesets
|
| 631 |
+
_localecodesets = {}
|
| 632 |
+
# current global domain, `messages' used for compatibility w/ GNU gettext
|
| 633 |
+
_current_domain = 'messages'
|
| 634 |
+
|
| 635 |
+
|
| 636 |
+
def textdomain(domain=None):
|
| 637 |
+
global _current_domain
|
| 638 |
+
if domain is not None:
|
| 639 |
+
_current_domain = domain
|
| 640 |
+
return _current_domain
|
| 641 |
+
|
| 642 |
+
|
| 643 |
+
def bindtextdomain(domain, localedir=None):
|
| 644 |
+
global _localedirs
|
| 645 |
+
if localedir is not None:
|
| 646 |
+
_localedirs[domain] = localedir
|
| 647 |
+
return _localedirs.get(domain, _default_localedir)
|
| 648 |
+
|
| 649 |
+
|
| 650 |
+
def bind_textdomain_codeset(domain, codeset=None):
|
| 651 |
+
import warnings
|
| 652 |
+
warnings.warn('bind_textdomain_codeset() is deprecated',
|
| 653 |
+
DeprecationWarning, 2)
|
| 654 |
+
global _localecodesets
|
| 655 |
+
if codeset is not None:
|
| 656 |
+
_localecodesets[domain] = codeset
|
| 657 |
+
return _localecodesets.get(domain)
|
| 658 |
+
|
| 659 |
+
|
| 660 |
+
def dgettext(domain, message):
|
| 661 |
+
try:
|
| 662 |
+
t = translation(domain, _localedirs.get(domain, None))
|
| 663 |
+
except OSError:
|
| 664 |
+
return message
|
| 665 |
+
return t.gettext(message)
|
| 666 |
+
|
| 667 |
+
def ldgettext(domain, message):
|
| 668 |
+
import warnings
|
| 669 |
+
warnings.warn('ldgettext() is deprecated, use dgettext() instead',
|
| 670 |
+
DeprecationWarning, 2)
|
| 671 |
+
codeset = _localecodesets.get(domain)
|
| 672 |
+
try:
|
| 673 |
+
with warnings.catch_warnings():
|
| 674 |
+
warnings.filterwarnings('ignore', r'.*\bparameter codeset\b.*',
|
| 675 |
+
DeprecationWarning)
|
| 676 |
+
t = translation(domain, _localedirs.get(domain, None), codeset=codeset)
|
| 677 |
+
except OSError:
|
| 678 |
+
return message.encode(codeset or locale.getpreferredencoding())
|
| 679 |
+
with warnings.catch_warnings():
|
| 680 |
+
warnings.filterwarnings('ignore', r'.*\blgettext\b.*',
|
| 681 |
+
DeprecationWarning)
|
| 682 |
+
return t.lgettext(message)
|
| 683 |
+
|
| 684 |
+
def dngettext(domain, msgid1, msgid2, n):
|
| 685 |
+
try:
|
| 686 |
+
t = translation(domain, _localedirs.get(domain, None))
|
| 687 |
+
except OSError:
|
| 688 |
+
if n == 1:
|
| 689 |
+
return msgid1
|
| 690 |
+
else:
|
| 691 |
+
return msgid2
|
| 692 |
+
return t.ngettext(msgid1, msgid2, n)
|
| 693 |
+
|
| 694 |
+
def ldngettext(domain, msgid1, msgid2, n):
|
| 695 |
+
import warnings
|
| 696 |
+
warnings.warn('ldngettext() is deprecated, use dngettext() instead',
|
| 697 |
+
DeprecationWarning, 2)
|
| 698 |
+
codeset = _localecodesets.get(domain)
|
| 699 |
+
try:
|
| 700 |
+
with warnings.catch_warnings():
|
| 701 |
+
warnings.filterwarnings('ignore', r'.*\bparameter codeset\b.*',
|
| 702 |
+
DeprecationWarning)
|
| 703 |
+
t = translation(domain, _localedirs.get(domain, None), codeset=codeset)
|
| 704 |
+
except OSError:
|
| 705 |
+
if n == 1:
|
| 706 |
+
tmsg = msgid1
|
| 707 |
+
else:
|
| 708 |
+
tmsg = msgid2
|
| 709 |
+
return tmsg.encode(codeset or locale.getpreferredencoding())
|
| 710 |
+
with warnings.catch_warnings():
|
| 711 |
+
warnings.filterwarnings('ignore', r'.*\blngettext\b.*',
|
| 712 |
+
DeprecationWarning)
|
| 713 |
+
return t.lngettext(msgid1, msgid2, n)
|
| 714 |
+
|
| 715 |
+
|
| 716 |
+
def dpgettext(domain, context, message):
|
| 717 |
+
try:
|
| 718 |
+
t = translation(domain, _localedirs.get(domain, None))
|
| 719 |
+
except OSError:
|
| 720 |
+
return message
|
| 721 |
+
return t.pgettext(context, message)
|
| 722 |
+
|
| 723 |
+
|
| 724 |
+
def dnpgettext(domain, context, msgid1, msgid2, n):
|
| 725 |
+
try:
|
| 726 |
+
t = translation(domain, _localedirs.get(domain, None))
|
| 727 |
+
except OSError:
|
| 728 |
+
if n == 1:
|
| 729 |
+
return msgid1
|
| 730 |
+
else:
|
| 731 |
+
return msgid2
|
| 732 |
+
return t.npgettext(context, msgid1, msgid2, n)
|
| 733 |
+
|
| 734 |
+
|
| 735 |
+
def gettext(message):
|
| 736 |
+
return dgettext(_current_domain, message)
|
| 737 |
+
|
| 738 |
+
def lgettext(message):
|
| 739 |
+
import warnings
|
| 740 |
+
warnings.warn('lgettext() is deprecated, use gettext() instead',
|
| 741 |
+
DeprecationWarning, 2)
|
| 742 |
+
with warnings.catch_warnings():
|
| 743 |
+
warnings.filterwarnings('ignore', r'.*\bldgettext\b.*',
|
| 744 |
+
DeprecationWarning)
|
| 745 |
+
return ldgettext(_current_domain, message)
|
| 746 |
+
|
| 747 |
+
def ngettext(msgid1, msgid2, n):
|
| 748 |
+
return dngettext(_current_domain, msgid1, msgid2, n)
|
| 749 |
+
|
| 750 |
+
def lngettext(msgid1, msgid2, n):
|
| 751 |
+
import warnings
|
| 752 |
+
warnings.warn('lngettext() is deprecated, use ngettext() instead',
|
| 753 |
+
DeprecationWarning, 2)
|
| 754 |
+
with warnings.catch_warnings():
|
| 755 |
+
warnings.filterwarnings('ignore', r'.*\bldngettext\b.*',
|
| 756 |
+
DeprecationWarning)
|
| 757 |
+
return ldngettext(_current_domain, msgid1, msgid2, n)
|
| 758 |
+
|
| 759 |
+
|
| 760 |
+
def pgettext(context, message):
|
| 761 |
+
return dpgettext(_current_domain, context, message)
|
| 762 |
+
|
| 763 |
+
|
| 764 |
+
def npgettext(context, msgid1, msgid2, n):
|
| 765 |
+
return dnpgettext(_current_domain, context, msgid1, msgid2, n)
|
| 766 |
+
|
| 767 |
+
|
| 768 |
+
# dcgettext() has been deemed unnecessary and is not implemented.
|
| 769 |
+
|
| 770 |
+
# James Henstridge's Catalog constructor from GNOME gettext. Documented usage
|
| 771 |
+
# was:
|
| 772 |
+
#
|
| 773 |
+
# import gettext
|
| 774 |
+
# cat = gettext.Catalog(PACKAGE, localedir=LOCALEDIR)
|
| 775 |
+
# _ = cat.gettext
|
| 776 |
+
# print _('Hello World')
|
| 777 |
+
|
| 778 |
+
# The resulting catalog object currently don't support access through a
|
| 779 |
+
# dictionary API, which was supported (but apparently unused) in GNOME
|
| 780 |
+
# gettext.
|
| 781 |
+
|
| 782 |
+
Catalog = translation
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/gzip.py
ADDED
|
@@ -0,0 +1,600 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Functions that read and write gzipped files.
|
| 2 |
+
|
| 3 |
+
The user of the file doesn't have to worry about the compression,
|
| 4 |
+
but random access is not allowed."""
|
| 5 |
+
|
| 6 |
+
# based on Andrew Kuchling's minigzip.py distributed with the zlib module
|
| 7 |
+
|
| 8 |
+
import struct, sys, time, os
|
| 9 |
+
import zlib
|
| 10 |
+
import builtins
|
| 11 |
+
import io
|
| 12 |
+
import _compression
|
| 13 |
+
|
| 14 |
+
__all__ = ["BadGzipFile", "GzipFile", "open", "compress", "decompress"]
|
| 15 |
+
|
| 16 |
+
FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
|
| 17 |
+
|
| 18 |
+
READ, WRITE = 1, 2
|
| 19 |
+
|
| 20 |
+
_COMPRESS_LEVEL_FAST = 1
|
| 21 |
+
_COMPRESS_LEVEL_TRADEOFF = 6
|
| 22 |
+
_COMPRESS_LEVEL_BEST = 9
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_BEST,
|
| 26 |
+
encoding=None, errors=None, newline=None):
|
| 27 |
+
"""Open a gzip-compressed file in binary or text mode.
|
| 28 |
+
|
| 29 |
+
The filename argument can be an actual filename (a str or bytes object), or
|
| 30 |
+
an existing file object to read from or write to.
|
| 31 |
+
|
| 32 |
+
The mode argument can be "r", "rb", "w", "wb", "x", "xb", "a" or "ab" for
|
| 33 |
+
binary mode, or "rt", "wt", "xt" or "at" for text mode. The default mode is
|
| 34 |
+
"rb", and the default compresslevel is 9.
|
| 35 |
+
|
| 36 |
+
For binary mode, this function is equivalent to the GzipFile constructor:
|
| 37 |
+
GzipFile(filename, mode, compresslevel). In this case, the encoding, errors
|
| 38 |
+
and newline arguments must not be provided.
|
| 39 |
+
|
| 40 |
+
For text mode, a GzipFile object is created, and wrapped in an
|
| 41 |
+
io.TextIOWrapper instance with the specified encoding, error handling
|
| 42 |
+
behavior, and line ending(s).
|
| 43 |
+
|
| 44 |
+
"""
|
| 45 |
+
if "t" in mode:
|
| 46 |
+
if "b" in mode:
|
| 47 |
+
raise ValueError("Invalid mode: %r" % (mode,))
|
| 48 |
+
else:
|
| 49 |
+
if encoding is not None:
|
| 50 |
+
raise ValueError("Argument 'encoding' not supported in binary mode")
|
| 51 |
+
if errors is not None:
|
| 52 |
+
raise ValueError("Argument 'errors' not supported in binary mode")
|
| 53 |
+
if newline is not None:
|
| 54 |
+
raise ValueError("Argument 'newline' not supported in binary mode")
|
| 55 |
+
|
| 56 |
+
gz_mode = mode.replace("t", "")
|
| 57 |
+
if isinstance(filename, (str, bytes, os.PathLike)):
|
| 58 |
+
binary_file = GzipFile(filename, gz_mode, compresslevel)
|
| 59 |
+
elif hasattr(filename, "read") or hasattr(filename, "write"):
|
| 60 |
+
binary_file = GzipFile(None, gz_mode, compresslevel, filename)
|
| 61 |
+
else:
|
| 62 |
+
raise TypeError("filename must be a str or bytes object, or a file")
|
| 63 |
+
|
| 64 |
+
if "t" in mode:
|
| 65 |
+
return io.TextIOWrapper(binary_file, encoding, errors, newline)
|
| 66 |
+
else:
|
| 67 |
+
return binary_file
|
| 68 |
+
|
| 69 |
+
def write32u(output, value):
|
| 70 |
+
# The L format writes the bit pattern correctly whether signed
|
| 71 |
+
# or unsigned.
|
| 72 |
+
output.write(struct.pack("<L", value))
|
| 73 |
+
|
| 74 |
+
class _PaddedFile:
|
| 75 |
+
"""Minimal read-only file object that prepends a string to the contents
|
| 76 |
+
of an actual file. Shouldn't be used outside of gzip.py, as it lacks
|
| 77 |
+
essential functionality."""
|
| 78 |
+
|
| 79 |
+
def __init__(self, f, prepend=b''):
|
| 80 |
+
self._buffer = prepend
|
| 81 |
+
self._length = len(prepend)
|
| 82 |
+
self.file = f
|
| 83 |
+
self._read = 0
|
| 84 |
+
|
| 85 |
+
def read(self, size):
|
| 86 |
+
if self._read is None:
|
| 87 |
+
return self.file.read(size)
|
| 88 |
+
if self._read + size <= self._length:
|
| 89 |
+
read = self._read
|
| 90 |
+
self._read += size
|
| 91 |
+
return self._buffer[read:self._read]
|
| 92 |
+
else:
|
| 93 |
+
read = self._read
|
| 94 |
+
self._read = None
|
| 95 |
+
return self._buffer[read:] + \
|
| 96 |
+
self.file.read(size-self._length+read)
|
| 97 |
+
|
| 98 |
+
def prepend(self, prepend=b''):
|
| 99 |
+
if self._read is None:
|
| 100 |
+
self._buffer = prepend
|
| 101 |
+
else: # Assume data was read since the last prepend() call
|
| 102 |
+
self._read -= len(prepend)
|
| 103 |
+
return
|
| 104 |
+
self._length = len(self._buffer)
|
| 105 |
+
self._read = 0
|
| 106 |
+
|
| 107 |
+
def seek(self, off):
|
| 108 |
+
self._read = None
|
| 109 |
+
self._buffer = None
|
| 110 |
+
return self.file.seek(off)
|
| 111 |
+
|
| 112 |
+
def seekable(self):
|
| 113 |
+
return True # Allows fast-forwarding even in unseekable streams
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
class BadGzipFile(OSError):
|
| 117 |
+
"""Exception raised in some cases for invalid gzip files."""
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
class GzipFile(_compression.BaseStream):
|
| 121 |
+
"""The GzipFile class simulates most of the methods of a file object with
|
| 122 |
+
the exception of the truncate() method.
|
| 123 |
+
|
| 124 |
+
This class only supports opening files in binary mode. If you need to open a
|
| 125 |
+
compressed file in text mode, use the gzip.open() function.
|
| 126 |
+
|
| 127 |
+
"""
|
| 128 |
+
|
| 129 |
+
# Overridden with internal file object to be closed, if only a filename
|
| 130 |
+
# is passed in
|
| 131 |
+
myfileobj = None
|
| 132 |
+
|
| 133 |
+
def __init__(self, filename=None, mode=None,
|
| 134 |
+
compresslevel=_COMPRESS_LEVEL_BEST, fileobj=None, mtime=None):
|
| 135 |
+
"""Constructor for the GzipFile class.
|
| 136 |
+
|
| 137 |
+
At least one of fileobj and filename must be given a
|
| 138 |
+
non-trivial value.
|
| 139 |
+
|
| 140 |
+
The new class instance is based on fileobj, which can be a regular
|
| 141 |
+
file, an io.BytesIO object, or any other object which simulates a file.
|
| 142 |
+
It defaults to None, in which case filename is opened to provide
|
| 143 |
+
a file object.
|
| 144 |
+
|
| 145 |
+
When fileobj is not None, the filename argument is only used to be
|
| 146 |
+
included in the gzip file header, which may include the original
|
| 147 |
+
filename of the uncompressed file. It defaults to the filename of
|
| 148 |
+
fileobj, if discernible; otherwise, it defaults to the empty string,
|
| 149 |
+
and in this case the original filename is not included in the header.
|
| 150 |
+
|
| 151 |
+
The mode argument can be any of 'r', 'rb', 'a', 'ab', 'w', 'wb', 'x', or
|
| 152 |
+
'xb' depending on whether the file will be read or written. The default
|
| 153 |
+
is the mode of fileobj if discernible; otherwise, the default is 'rb'.
|
| 154 |
+
A mode of 'r' is equivalent to one of 'rb', and similarly for 'w' and
|
| 155 |
+
'wb', 'a' and 'ab', and 'x' and 'xb'.
|
| 156 |
+
|
| 157 |
+
The compresslevel argument is an integer from 0 to 9 controlling the
|
| 158 |
+
level of compression; 1 is fastest and produces the least compression,
|
| 159 |
+
and 9 is slowest and produces the most compression. 0 is no compression
|
| 160 |
+
at all. The default is 9.
|
| 161 |
+
|
| 162 |
+
The mtime argument is an optional numeric timestamp to be written
|
| 163 |
+
to the last modification time field in the stream when compressing.
|
| 164 |
+
If omitted or None, the current time is used.
|
| 165 |
+
|
| 166 |
+
"""
|
| 167 |
+
|
| 168 |
+
if mode and ('t' in mode or 'U' in mode):
|
| 169 |
+
raise ValueError("Invalid mode: {!r}".format(mode))
|
| 170 |
+
if mode and 'b' not in mode:
|
| 171 |
+
mode += 'b'
|
| 172 |
+
if fileobj is None:
|
| 173 |
+
fileobj = self.myfileobj = builtins.open(filename, mode or 'rb')
|
| 174 |
+
if filename is None:
|
| 175 |
+
filename = getattr(fileobj, 'name', '')
|
| 176 |
+
if not isinstance(filename, (str, bytes)):
|
| 177 |
+
filename = ''
|
| 178 |
+
else:
|
| 179 |
+
filename = os.fspath(filename)
|
| 180 |
+
if mode is None:
|
| 181 |
+
mode = getattr(fileobj, 'mode', 'rb')
|
| 182 |
+
|
| 183 |
+
if mode.startswith('r'):
|
| 184 |
+
self.mode = READ
|
| 185 |
+
raw = _GzipReader(fileobj)
|
| 186 |
+
self._buffer = io.BufferedReader(raw)
|
| 187 |
+
self.name = filename
|
| 188 |
+
|
| 189 |
+
elif mode.startswith(('w', 'a', 'x')):
|
| 190 |
+
self.mode = WRITE
|
| 191 |
+
self._init_write(filename)
|
| 192 |
+
self.compress = zlib.compressobj(compresslevel,
|
| 193 |
+
zlib.DEFLATED,
|
| 194 |
+
-zlib.MAX_WBITS,
|
| 195 |
+
zlib.DEF_MEM_LEVEL,
|
| 196 |
+
0)
|
| 197 |
+
self._write_mtime = mtime
|
| 198 |
+
else:
|
| 199 |
+
raise ValueError("Invalid mode: {!r}".format(mode))
|
| 200 |
+
|
| 201 |
+
self.fileobj = fileobj
|
| 202 |
+
|
| 203 |
+
if self.mode == WRITE:
|
| 204 |
+
self._write_gzip_header(compresslevel)
|
| 205 |
+
|
| 206 |
+
@property
|
| 207 |
+
def filename(self):
|
| 208 |
+
import warnings
|
| 209 |
+
warnings.warn("use the name attribute", DeprecationWarning, 2)
|
| 210 |
+
if self.mode == WRITE and self.name[-3:] != ".gz":
|
| 211 |
+
return self.name + ".gz"
|
| 212 |
+
return self.name
|
| 213 |
+
|
| 214 |
+
@property
|
| 215 |
+
def mtime(self):
|
| 216 |
+
"""Last modification time read from stream, or None"""
|
| 217 |
+
return self._buffer.raw._last_mtime
|
| 218 |
+
|
| 219 |
+
def __repr__(self):
|
| 220 |
+
s = repr(self.fileobj)
|
| 221 |
+
return '<gzip ' + s[1:-1] + ' ' + hex(id(self)) + '>'
|
| 222 |
+
|
| 223 |
+
def _init_write(self, filename):
|
| 224 |
+
self.name = filename
|
| 225 |
+
self.crc = zlib.crc32(b"")
|
| 226 |
+
self.size = 0
|
| 227 |
+
self.writebuf = []
|
| 228 |
+
self.bufsize = 0
|
| 229 |
+
self.offset = 0 # Current file offset for seek(), tell(), etc
|
| 230 |
+
|
| 231 |
+
def _write_gzip_header(self, compresslevel):
|
| 232 |
+
self.fileobj.write(b'\037\213') # magic header
|
| 233 |
+
self.fileobj.write(b'\010') # compression method
|
| 234 |
+
try:
|
| 235 |
+
# RFC 1952 requires the FNAME field to be Latin-1. Do not
|
| 236 |
+
# include filenames that cannot be represented that way.
|
| 237 |
+
fname = os.path.basename(self.name)
|
| 238 |
+
if not isinstance(fname, bytes):
|
| 239 |
+
fname = fname.encode('latin-1')
|
| 240 |
+
if fname.endswith(b'.gz'):
|
| 241 |
+
fname = fname[:-3]
|
| 242 |
+
except UnicodeEncodeError:
|
| 243 |
+
fname = b''
|
| 244 |
+
flags = 0
|
| 245 |
+
if fname:
|
| 246 |
+
flags = FNAME
|
| 247 |
+
self.fileobj.write(chr(flags).encode('latin-1'))
|
| 248 |
+
mtime = self._write_mtime
|
| 249 |
+
if mtime is None:
|
| 250 |
+
mtime = time.time()
|
| 251 |
+
write32u(self.fileobj, int(mtime))
|
| 252 |
+
if compresslevel == _COMPRESS_LEVEL_BEST:
|
| 253 |
+
xfl = b'\002'
|
| 254 |
+
elif compresslevel == _COMPRESS_LEVEL_FAST:
|
| 255 |
+
xfl = b'\004'
|
| 256 |
+
else:
|
| 257 |
+
xfl = b'\000'
|
| 258 |
+
self.fileobj.write(xfl)
|
| 259 |
+
self.fileobj.write(b'\377')
|
| 260 |
+
if fname:
|
| 261 |
+
self.fileobj.write(fname + b'\000')
|
| 262 |
+
|
| 263 |
+
def write(self,data):
|
| 264 |
+
self._check_not_closed()
|
| 265 |
+
if self.mode != WRITE:
|
| 266 |
+
import errno
|
| 267 |
+
raise OSError(errno.EBADF, "write() on read-only GzipFile object")
|
| 268 |
+
|
| 269 |
+
if self.fileobj is None:
|
| 270 |
+
raise ValueError("write() on closed GzipFile object")
|
| 271 |
+
|
| 272 |
+
if isinstance(data, bytes):
|
| 273 |
+
length = len(data)
|
| 274 |
+
else:
|
| 275 |
+
# accept any data that supports the buffer protocol
|
| 276 |
+
data = memoryview(data)
|
| 277 |
+
length = data.nbytes
|
| 278 |
+
|
| 279 |
+
if length > 0:
|
| 280 |
+
self.fileobj.write(self.compress.compress(data))
|
| 281 |
+
self.size += length
|
| 282 |
+
self.crc = zlib.crc32(data, self.crc)
|
| 283 |
+
self.offset += length
|
| 284 |
+
|
| 285 |
+
return length
|
| 286 |
+
|
| 287 |
+
def read(self, size=-1):
|
| 288 |
+
self._check_not_closed()
|
| 289 |
+
if self.mode != READ:
|
| 290 |
+
import errno
|
| 291 |
+
raise OSError(errno.EBADF, "read() on write-only GzipFile object")
|
| 292 |
+
return self._buffer.read(size)
|
| 293 |
+
|
| 294 |
+
def read1(self, size=-1):
|
| 295 |
+
"""Implements BufferedIOBase.read1()
|
| 296 |
+
|
| 297 |
+
Reads up to a buffer's worth of data if size is negative."""
|
| 298 |
+
self._check_not_closed()
|
| 299 |
+
if self.mode != READ:
|
| 300 |
+
import errno
|
| 301 |
+
raise OSError(errno.EBADF, "read1() on write-only GzipFile object")
|
| 302 |
+
|
| 303 |
+
if size < 0:
|
| 304 |
+
size = io.DEFAULT_BUFFER_SIZE
|
| 305 |
+
return self._buffer.read1(size)
|
| 306 |
+
|
| 307 |
+
def peek(self, n):
|
| 308 |
+
self._check_not_closed()
|
| 309 |
+
if self.mode != READ:
|
| 310 |
+
import errno
|
| 311 |
+
raise OSError(errno.EBADF, "peek() on write-only GzipFile object")
|
| 312 |
+
return self._buffer.peek(n)
|
| 313 |
+
|
| 314 |
+
@property
|
| 315 |
+
def closed(self):
|
| 316 |
+
return self.fileobj is None
|
| 317 |
+
|
| 318 |
+
def close(self):
|
| 319 |
+
fileobj = self.fileobj
|
| 320 |
+
if fileobj is None:
|
| 321 |
+
return
|
| 322 |
+
self.fileobj = None
|
| 323 |
+
try:
|
| 324 |
+
if self.mode == WRITE:
|
| 325 |
+
fileobj.write(self.compress.flush())
|
| 326 |
+
write32u(fileobj, self.crc)
|
| 327 |
+
# self.size may exceed 2 GiB, or even 4 GiB
|
| 328 |
+
write32u(fileobj, self.size & 0xffffffff)
|
| 329 |
+
elif self.mode == READ:
|
| 330 |
+
self._buffer.close()
|
| 331 |
+
finally:
|
| 332 |
+
myfileobj = self.myfileobj
|
| 333 |
+
if myfileobj:
|
| 334 |
+
self.myfileobj = None
|
| 335 |
+
myfileobj.close()
|
| 336 |
+
|
| 337 |
+
def flush(self,zlib_mode=zlib.Z_SYNC_FLUSH):
|
| 338 |
+
self._check_not_closed()
|
| 339 |
+
if self.mode == WRITE:
|
| 340 |
+
# Ensure the compressor's buffer is flushed
|
| 341 |
+
self.fileobj.write(self.compress.flush(zlib_mode))
|
| 342 |
+
self.fileobj.flush()
|
| 343 |
+
|
| 344 |
+
def fileno(self):
|
| 345 |
+
"""Invoke the underlying file object's fileno() method.
|
| 346 |
+
|
| 347 |
+
This will raise AttributeError if the underlying file object
|
| 348 |
+
doesn't support fileno().
|
| 349 |
+
"""
|
| 350 |
+
return self.fileobj.fileno()
|
| 351 |
+
|
| 352 |
+
def rewind(self):
|
| 353 |
+
'''Return the uncompressed stream file position indicator to the
|
| 354 |
+
beginning of the file'''
|
| 355 |
+
if self.mode != READ:
|
| 356 |
+
raise OSError("Can't rewind in write mode")
|
| 357 |
+
self._buffer.seek(0)
|
| 358 |
+
|
| 359 |
+
def readable(self):
|
| 360 |
+
return self.mode == READ
|
| 361 |
+
|
| 362 |
+
def writable(self):
|
| 363 |
+
return self.mode == WRITE
|
| 364 |
+
|
| 365 |
+
def seekable(self):
|
| 366 |
+
return True
|
| 367 |
+
|
| 368 |
+
def seek(self, offset, whence=io.SEEK_SET):
|
| 369 |
+
if self.mode == WRITE:
|
| 370 |
+
if whence != io.SEEK_SET:
|
| 371 |
+
if whence == io.SEEK_CUR:
|
| 372 |
+
offset = self.offset + offset
|
| 373 |
+
else:
|
| 374 |
+
raise ValueError('Seek from end not supported')
|
| 375 |
+
if offset < self.offset:
|
| 376 |
+
raise OSError('Negative seek in write mode')
|
| 377 |
+
count = offset - self.offset
|
| 378 |
+
chunk = b'\0' * 1024
|
| 379 |
+
for i in range(count // 1024):
|
| 380 |
+
self.write(chunk)
|
| 381 |
+
self.write(b'\0' * (count % 1024))
|
| 382 |
+
elif self.mode == READ:
|
| 383 |
+
self._check_not_closed()
|
| 384 |
+
return self._buffer.seek(offset, whence)
|
| 385 |
+
|
| 386 |
+
return self.offset
|
| 387 |
+
|
| 388 |
+
def readline(self, size=-1):
|
| 389 |
+
self._check_not_closed()
|
| 390 |
+
return self._buffer.readline(size)
|
| 391 |
+
|
| 392 |
+
|
| 393 |
+
class _GzipReader(_compression.DecompressReader):
|
| 394 |
+
def __init__(self, fp):
|
| 395 |
+
super().__init__(_PaddedFile(fp), zlib.decompressobj,
|
| 396 |
+
wbits=-zlib.MAX_WBITS)
|
| 397 |
+
# Set flag indicating start of a new member
|
| 398 |
+
self._new_member = True
|
| 399 |
+
self._last_mtime = None
|
| 400 |
+
|
| 401 |
+
def _init_read(self):
|
| 402 |
+
self._crc = zlib.crc32(b"")
|
| 403 |
+
self._stream_size = 0 # Decompressed size of unconcatenated stream
|
| 404 |
+
|
| 405 |
+
def _read_exact(self, n):
|
| 406 |
+
'''Read exactly *n* bytes from `self._fp`
|
| 407 |
+
|
| 408 |
+
This method is required because self._fp may be unbuffered,
|
| 409 |
+
i.e. return short reads.
|
| 410 |
+
'''
|
| 411 |
+
|
| 412 |
+
data = self._fp.read(n)
|
| 413 |
+
while len(data) < n:
|
| 414 |
+
b = self._fp.read(n - len(data))
|
| 415 |
+
if not b:
|
| 416 |
+
raise EOFError("Compressed file ended before the "
|
| 417 |
+
"end-of-stream marker was reached")
|
| 418 |
+
data += b
|
| 419 |
+
return data
|
| 420 |
+
|
| 421 |
+
def _read_gzip_header(self):
|
| 422 |
+
magic = self._fp.read(2)
|
| 423 |
+
if magic == b'':
|
| 424 |
+
return False
|
| 425 |
+
|
| 426 |
+
if magic != b'\037\213':
|
| 427 |
+
raise BadGzipFile('Not a gzipped file (%r)' % magic)
|
| 428 |
+
|
| 429 |
+
(method, flag,
|
| 430 |
+
self._last_mtime) = struct.unpack("<BBIxx", self._read_exact(8))
|
| 431 |
+
if method != 8:
|
| 432 |
+
raise BadGzipFile('Unknown compression method')
|
| 433 |
+
|
| 434 |
+
if flag & FEXTRA:
|
| 435 |
+
# Read & discard the extra field, if present
|
| 436 |
+
extra_len, = struct.unpack("<H", self._read_exact(2))
|
| 437 |
+
self._read_exact(extra_len)
|
| 438 |
+
if flag & FNAME:
|
| 439 |
+
# Read and discard a null-terminated string containing the filename
|
| 440 |
+
while True:
|
| 441 |
+
s = self._fp.read(1)
|
| 442 |
+
if not s or s==b'\000':
|
| 443 |
+
break
|
| 444 |
+
if flag & FCOMMENT:
|
| 445 |
+
# Read and discard a null-terminated string containing a comment
|
| 446 |
+
while True:
|
| 447 |
+
s = self._fp.read(1)
|
| 448 |
+
if not s or s==b'\000':
|
| 449 |
+
break
|
| 450 |
+
if flag & FHCRC:
|
| 451 |
+
self._read_exact(2) # Read & discard the 16-bit header CRC
|
| 452 |
+
return True
|
| 453 |
+
|
| 454 |
+
def read(self, size=-1):
|
| 455 |
+
if size < 0:
|
| 456 |
+
return self.readall()
|
| 457 |
+
# size=0 is special because decompress(max_length=0) is not supported
|
| 458 |
+
if not size:
|
| 459 |
+
return b""
|
| 460 |
+
|
| 461 |
+
# For certain input data, a single
|
| 462 |
+
# call to decompress() may not return
|
| 463 |
+
# any data. In this case, retry until we get some data or reach EOF.
|
| 464 |
+
while True:
|
| 465 |
+
if self._decompressor.eof:
|
| 466 |
+
# Ending case: we've come to the end of a member in the file,
|
| 467 |
+
# so finish up this member, and read a new gzip header.
|
| 468 |
+
# Check the CRC and file size, and set the flag so we read
|
| 469 |
+
# a new member
|
| 470 |
+
self._read_eof()
|
| 471 |
+
self._new_member = True
|
| 472 |
+
self._decompressor = self._decomp_factory(
|
| 473 |
+
**self._decomp_args)
|
| 474 |
+
|
| 475 |
+
if self._new_member:
|
| 476 |
+
# If the _new_member flag is set, we have to
|
| 477 |
+
# jump to the next member, if there is one.
|
| 478 |
+
self._init_read()
|
| 479 |
+
if not self._read_gzip_header():
|
| 480 |
+
self._size = self._pos
|
| 481 |
+
return b""
|
| 482 |
+
self._new_member = False
|
| 483 |
+
|
| 484 |
+
# Read a chunk of data from the file
|
| 485 |
+
buf = self._fp.read(io.DEFAULT_BUFFER_SIZE)
|
| 486 |
+
|
| 487 |
+
uncompress = self._decompressor.decompress(buf, size)
|
| 488 |
+
if self._decompressor.unconsumed_tail != b"":
|
| 489 |
+
self._fp.prepend(self._decompressor.unconsumed_tail)
|
| 490 |
+
elif self._decompressor.unused_data != b"":
|
| 491 |
+
# Prepend the already read bytes to the fileobj so they can
|
| 492 |
+
# be seen by _read_eof() and _read_gzip_header()
|
| 493 |
+
self._fp.prepend(self._decompressor.unused_data)
|
| 494 |
+
|
| 495 |
+
if uncompress != b"":
|
| 496 |
+
break
|
| 497 |
+
if buf == b"":
|
| 498 |
+
raise EOFError("Compressed file ended before the "
|
| 499 |
+
"end-of-stream marker was reached")
|
| 500 |
+
|
| 501 |
+
self._add_read_data( uncompress )
|
| 502 |
+
self._pos += len(uncompress)
|
| 503 |
+
return uncompress
|
| 504 |
+
|
| 505 |
+
def _add_read_data(self, data):
|
| 506 |
+
self._crc = zlib.crc32(data, self._crc)
|
| 507 |
+
self._stream_size = self._stream_size + len(data)
|
| 508 |
+
|
| 509 |
+
def _read_eof(self):
|
| 510 |
+
# We've read to the end of the file
|
| 511 |
+
# We check the that the computed CRC and size of the
|
| 512 |
+
# uncompressed data matches the stored values. Note that the size
|
| 513 |
+
# stored is the true file size mod 2**32.
|
| 514 |
+
crc32, isize = struct.unpack("<II", self._read_exact(8))
|
| 515 |
+
if crc32 != self._crc:
|
| 516 |
+
raise BadGzipFile("CRC check failed %s != %s" % (hex(crc32),
|
| 517 |
+
hex(self._crc)))
|
| 518 |
+
elif isize != (self._stream_size & 0xffffffff):
|
| 519 |
+
raise BadGzipFile("Incorrect length of data produced")
|
| 520 |
+
|
| 521 |
+
# Gzip files can be padded with zeroes and still have archives.
|
| 522 |
+
# Consume all zero bytes and set the file position to the first
|
| 523 |
+
# non-zero byte. See http://www.gzip.org/#faq8
|
| 524 |
+
c = b"\x00"
|
| 525 |
+
while c == b"\x00":
|
| 526 |
+
c = self._fp.read(1)
|
| 527 |
+
if c:
|
| 528 |
+
self._fp.prepend(c)
|
| 529 |
+
|
| 530 |
+
def _rewind(self):
|
| 531 |
+
super()._rewind()
|
| 532 |
+
self._new_member = True
|
| 533 |
+
|
| 534 |
+
def compress(data, compresslevel=_COMPRESS_LEVEL_BEST, *, mtime=None):
|
| 535 |
+
"""Compress data in one shot and return the compressed string.
|
| 536 |
+
Optional argument is the compression level, in range of 0-9.
|
| 537 |
+
"""
|
| 538 |
+
buf = io.BytesIO()
|
| 539 |
+
with GzipFile(fileobj=buf, mode='wb', compresslevel=compresslevel, mtime=mtime) as f:
|
| 540 |
+
f.write(data)
|
| 541 |
+
return buf.getvalue()
|
| 542 |
+
|
| 543 |
+
def decompress(data):
|
| 544 |
+
"""Decompress a gzip compressed string in one shot.
|
| 545 |
+
Return the decompressed string.
|
| 546 |
+
"""
|
| 547 |
+
with GzipFile(fileobj=io.BytesIO(data)) as f:
|
| 548 |
+
return f.read()
|
| 549 |
+
|
| 550 |
+
|
| 551 |
+
def main():
|
| 552 |
+
from argparse import ArgumentParser
|
| 553 |
+
parser = ArgumentParser(description=
|
| 554 |
+
"A simple command line interface for the gzip module: act like gzip, "
|
| 555 |
+
"but do not delete the input file.")
|
| 556 |
+
group = parser.add_mutually_exclusive_group()
|
| 557 |
+
group.add_argument('--fast', action='store_true', help='compress faster')
|
| 558 |
+
group.add_argument('--best', action='store_true', help='compress better')
|
| 559 |
+
group.add_argument("-d", "--decompress", action="store_true",
|
| 560 |
+
help="act like gunzip instead of gzip")
|
| 561 |
+
|
| 562 |
+
parser.add_argument("args", nargs="*", default=["-"], metavar='file')
|
| 563 |
+
args = parser.parse_args()
|
| 564 |
+
|
| 565 |
+
compresslevel = _COMPRESS_LEVEL_TRADEOFF
|
| 566 |
+
if args.fast:
|
| 567 |
+
compresslevel = _COMPRESS_LEVEL_FAST
|
| 568 |
+
elif args.best:
|
| 569 |
+
compresslevel = _COMPRESS_LEVEL_BEST
|
| 570 |
+
|
| 571 |
+
for arg in args.args:
|
| 572 |
+
if args.decompress:
|
| 573 |
+
if arg == "-":
|
| 574 |
+
f = GzipFile(filename="", mode="rb", fileobj=sys.stdin.buffer)
|
| 575 |
+
g = sys.stdout.buffer
|
| 576 |
+
else:
|
| 577 |
+
if arg[-3:] != ".gz":
|
| 578 |
+
sys.exit(f"filename doesn't end in .gz: {arg!r}")
|
| 579 |
+
f = open(arg, "rb")
|
| 580 |
+
g = builtins.open(arg[:-3], "wb")
|
| 581 |
+
else:
|
| 582 |
+
if arg == "-":
|
| 583 |
+
f = sys.stdin.buffer
|
| 584 |
+
g = GzipFile(filename="", mode="wb", fileobj=sys.stdout.buffer,
|
| 585 |
+
compresslevel=compresslevel)
|
| 586 |
+
else:
|
| 587 |
+
f = builtins.open(arg, "rb")
|
| 588 |
+
g = open(arg + ".gz", "wb")
|
| 589 |
+
while True:
|
| 590 |
+
chunk = f.read(1024)
|
| 591 |
+
if not chunk:
|
| 592 |
+
break
|
| 593 |
+
g.write(chunk)
|
| 594 |
+
if g is not sys.stdout.buffer:
|
| 595 |
+
g.close()
|
| 596 |
+
if f is not sys.stdin.buffer:
|
| 597 |
+
f.close()
|
| 598 |
+
|
| 599 |
+
if __name__ == '__main__':
|
| 600 |
+
main()
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/hashlib.py
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#. Copyright (C) 2005-2010 Gregory P. Smith (greg@krypto.org)
|
| 2 |
+
# Licensed to PSF under a Contributor Agreement.
|
| 3 |
+
#
|
| 4 |
+
|
| 5 |
+
__doc__ = """hashlib module - A common interface to many hash functions.
|
| 6 |
+
|
| 7 |
+
new(name, data=b'', **kwargs) - returns a new hash object implementing the
|
| 8 |
+
given hash function; initializing the hash
|
| 9 |
+
using the given binary data.
|
| 10 |
+
|
| 11 |
+
Named constructor functions are also available, these are faster
|
| 12 |
+
than using new(name):
|
| 13 |
+
|
| 14 |
+
md5(), sha1(), sha224(), sha256(), sha384(), sha512(), blake2b(), blake2s(),
|
| 15 |
+
sha3_224, sha3_256, sha3_384, sha3_512, shake_128, and shake_256.
|
| 16 |
+
|
| 17 |
+
More algorithms may be available on your platform but the above are guaranteed
|
| 18 |
+
to exist. See the algorithms_guaranteed and algorithms_available attributes
|
| 19 |
+
to find out what algorithm names can be passed to new().
|
| 20 |
+
|
| 21 |
+
NOTE: If you want the adler32 or crc32 hash functions they are available in
|
| 22 |
+
the zlib module.
|
| 23 |
+
|
| 24 |
+
Choose your hash function wisely. Some have known collision weaknesses.
|
| 25 |
+
sha384 and sha512 will be slow on 32 bit platforms.
|
| 26 |
+
|
| 27 |
+
Hash objects have these methods:
|
| 28 |
+
- update(data): Update the hash object with the bytes in data. Repeated calls
|
| 29 |
+
are equivalent to a single call with the concatenation of all
|
| 30 |
+
the arguments.
|
| 31 |
+
- digest(): Return the digest of the bytes passed to the update() method
|
| 32 |
+
so far as a bytes object.
|
| 33 |
+
- hexdigest(): Like digest() except the digest is returned as a string
|
| 34 |
+
of double length, containing only hexadecimal digits.
|
| 35 |
+
- copy(): Return a copy (clone) of the hash object. This can be used to
|
| 36 |
+
efficiently compute the digests of datas that share a common
|
| 37 |
+
initial substring.
|
| 38 |
+
|
| 39 |
+
For example, to obtain the digest of the byte string 'Nobody inspects the
|
| 40 |
+
spammish repetition':
|
| 41 |
+
|
| 42 |
+
>>> import hashlib
|
| 43 |
+
>>> m = hashlib.md5()
|
| 44 |
+
>>> m.update(b"Nobody inspects")
|
| 45 |
+
>>> m.update(b" the spammish repetition")
|
| 46 |
+
>>> m.digest()
|
| 47 |
+
b'\\xbbd\\x9c\\x83\\xdd\\x1e\\xa5\\xc9\\xd9\\xde\\xc9\\xa1\\x8d\\xf0\\xff\\xe9'
|
| 48 |
+
|
| 49 |
+
More condensed:
|
| 50 |
+
|
| 51 |
+
>>> hashlib.sha224(b"Nobody inspects the spammish repetition").hexdigest()
|
| 52 |
+
'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
|
| 53 |
+
|
| 54 |
+
"""
|
| 55 |
+
|
| 56 |
+
# This tuple and __get_builtin_constructor() must be modified if a new
|
| 57 |
+
# always available algorithm is added.
|
| 58 |
+
__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
|
| 59 |
+
'blake2b', 'blake2s',
|
| 60 |
+
'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
|
| 61 |
+
'shake_128', 'shake_256')
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
algorithms_guaranteed = set(__always_supported)
|
| 65 |
+
algorithms_available = set(__always_supported)
|
| 66 |
+
|
| 67 |
+
__all__ = __always_supported + ('new', 'algorithms_guaranteed',
|
| 68 |
+
'algorithms_available', 'pbkdf2_hmac')
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
__builtin_constructor_cache = {}
|
| 72 |
+
|
| 73 |
+
__block_openssl_constructor = {
|
| 74 |
+
'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
|
| 75 |
+
'shake_128', 'shake_256',
|
| 76 |
+
'blake2b', 'blake2s',
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
def __get_builtin_constructor(name):
|
| 80 |
+
cache = __builtin_constructor_cache
|
| 81 |
+
constructor = cache.get(name)
|
| 82 |
+
if constructor is not None:
|
| 83 |
+
return constructor
|
| 84 |
+
try:
|
| 85 |
+
if name in {'SHA1', 'sha1'}:
|
| 86 |
+
import _sha1
|
| 87 |
+
cache['SHA1'] = cache['sha1'] = _sha1.sha1
|
| 88 |
+
elif name in {'MD5', 'md5'}:
|
| 89 |
+
import _md5
|
| 90 |
+
cache['MD5'] = cache['md5'] = _md5.md5
|
| 91 |
+
elif name in {'SHA256', 'sha256', 'SHA224', 'sha224'}:
|
| 92 |
+
import _sha256
|
| 93 |
+
cache['SHA224'] = cache['sha224'] = _sha256.sha224
|
| 94 |
+
cache['SHA256'] = cache['sha256'] = _sha256.sha256
|
| 95 |
+
elif name in {'SHA512', 'sha512', 'SHA384', 'sha384'}:
|
| 96 |
+
import _sha512
|
| 97 |
+
cache['SHA384'] = cache['sha384'] = _sha512.sha384
|
| 98 |
+
cache['SHA512'] = cache['sha512'] = _sha512.sha512
|
| 99 |
+
elif name in {'blake2b', 'blake2s'}:
|
| 100 |
+
import _blake2
|
| 101 |
+
cache['blake2b'] = _blake2.blake2b
|
| 102 |
+
cache['blake2s'] = _blake2.blake2s
|
| 103 |
+
elif name in {'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512'}:
|
| 104 |
+
import _sha3
|
| 105 |
+
cache['sha3_224'] = _sha3.sha3_224
|
| 106 |
+
cache['sha3_256'] = _sha3.sha3_256
|
| 107 |
+
cache['sha3_384'] = _sha3.sha3_384
|
| 108 |
+
cache['sha3_512'] = _sha3.sha3_512
|
| 109 |
+
elif name in {'shake_128', 'shake_256'}:
|
| 110 |
+
import _sha3
|
| 111 |
+
cache['shake_128'] = _sha3.shake_128
|
| 112 |
+
cache['shake_256'] = _sha3.shake_256
|
| 113 |
+
except ImportError:
|
| 114 |
+
pass # no extension module, this hash is unsupported.
|
| 115 |
+
|
| 116 |
+
constructor = cache.get(name)
|
| 117 |
+
if constructor is not None:
|
| 118 |
+
return constructor
|
| 119 |
+
|
| 120 |
+
raise ValueError('unsupported hash type ' + name)
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def __get_openssl_constructor(name):
|
| 124 |
+
if name in __block_openssl_constructor:
|
| 125 |
+
# Prefer our blake2 and sha3 implementation.
|
| 126 |
+
return __get_builtin_constructor(name)
|
| 127 |
+
try:
|
| 128 |
+
f = getattr(_hashlib, 'openssl_' + name)
|
| 129 |
+
# Allow the C module to raise ValueError. The function will be
|
| 130 |
+
# defined but the hash not actually available thanks to OpenSSL.
|
| 131 |
+
f()
|
| 132 |
+
# Use the C function directly (very fast)
|
| 133 |
+
return f
|
| 134 |
+
except (AttributeError, ValueError):
|
| 135 |
+
return __get_builtin_constructor(name)
|
| 136 |
+
|
| 137 |
+
|
| 138 |
+
def __py_new(name, data=b'', **kwargs):
|
| 139 |
+
"""new(name, data=b'', **kwargs) - Return a new hashing object using the
|
| 140 |
+
named algorithm; optionally initialized with data (which must be
|
| 141 |
+
a bytes-like object).
|
| 142 |
+
"""
|
| 143 |
+
return __get_builtin_constructor(name)(data, **kwargs)
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
def __hash_new(name, data=b'', **kwargs):
|
| 147 |
+
"""new(name, data=b'') - Return a new hashing object using the named algorithm;
|
| 148 |
+
optionally initialized with data (which must be a bytes-like object).
|
| 149 |
+
"""
|
| 150 |
+
if name in __block_openssl_constructor:
|
| 151 |
+
# Prefer our blake2 and sha3 implementation
|
| 152 |
+
# OpenSSL 1.1.0 comes with a limited implementation of blake2b/s.
|
| 153 |
+
# It does neither support keyed blake2 nor advanced features like
|
| 154 |
+
# salt, personal, tree hashing or SSE.
|
| 155 |
+
return __get_builtin_constructor(name)(data, **kwargs)
|
| 156 |
+
try:
|
| 157 |
+
return _hashlib.new(name, data)
|
| 158 |
+
except ValueError:
|
| 159 |
+
# If the _hashlib module (OpenSSL) doesn't support the named
|
| 160 |
+
# hash, try using our builtin implementations.
|
| 161 |
+
# This allows for SHA224/256 and SHA384/512 support even though
|
| 162 |
+
# the OpenSSL library prior to 0.9.8 doesn't provide them.
|
| 163 |
+
return __get_builtin_constructor(name)(data)
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
try:
|
| 167 |
+
import _hashlib
|
| 168 |
+
new = __hash_new
|
| 169 |
+
__get_hash = __get_openssl_constructor
|
| 170 |
+
algorithms_available = algorithms_available.union(
|
| 171 |
+
_hashlib.openssl_md_meth_names)
|
| 172 |
+
except ImportError:
|
| 173 |
+
new = __py_new
|
| 174 |
+
__get_hash = __get_builtin_constructor
|
| 175 |
+
|
| 176 |
+
try:
|
| 177 |
+
# OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA
|
| 178 |
+
from _hashlib import pbkdf2_hmac
|
| 179 |
+
except ImportError:
|
| 180 |
+
_trans_5C = bytes((x ^ 0x5C) for x in range(256))
|
| 181 |
+
_trans_36 = bytes((x ^ 0x36) for x in range(256))
|
| 182 |
+
|
| 183 |
+
def pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None):
|
| 184 |
+
"""Password based key derivation function 2 (PKCS #5 v2.0)
|
| 185 |
+
|
| 186 |
+
This Python implementations based on the hmac module about as fast
|
| 187 |
+
as OpenSSL's PKCS5_PBKDF2_HMAC for short passwords and much faster
|
| 188 |
+
for long passwords.
|
| 189 |
+
"""
|
| 190 |
+
if not isinstance(hash_name, str):
|
| 191 |
+
raise TypeError(hash_name)
|
| 192 |
+
|
| 193 |
+
if not isinstance(password, (bytes, bytearray)):
|
| 194 |
+
password = bytes(memoryview(password))
|
| 195 |
+
if not isinstance(salt, (bytes, bytearray)):
|
| 196 |
+
salt = bytes(memoryview(salt))
|
| 197 |
+
|
| 198 |
+
# Fast inline HMAC implementation
|
| 199 |
+
inner = new(hash_name)
|
| 200 |
+
outer = new(hash_name)
|
| 201 |
+
blocksize = getattr(inner, 'block_size', 64)
|
| 202 |
+
if len(password) > blocksize:
|
| 203 |
+
password = new(hash_name, password).digest()
|
| 204 |
+
password = password + b'\x00' * (blocksize - len(password))
|
| 205 |
+
inner.update(password.translate(_trans_36))
|
| 206 |
+
outer.update(password.translate(_trans_5C))
|
| 207 |
+
|
| 208 |
+
def prf(msg, inner=inner, outer=outer):
|
| 209 |
+
# PBKDF2_HMAC uses the password as key. We can re-use the same
|
| 210 |
+
# digest objects and just update copies to skip initialization.
|
| 211 |
+
icpy = inner.copy()
|
| 212 |
+
ocpy = outer.copy()
|
| 213 |
+
icpy.update(msg)
|
| 214 |
+
ocpy.update(icpy.digest())
|
| 215 |
+
return ocpy.digest()
|
| 216 |
+
|
| 217 |
+
if iterations < 1:
|
| 218 |
+
raise ValueError(iterations)
|
| 219 |
+
if dklen is None:
|
| 220 |
+
dklen = outer.digest_size
|
| 221 |
+
if dklen < 1:
|
| 222 |
+
raise ValueError(dklen)
|
| 223 |
+
|
| 224 |
+
dkey = b''
|
| 225 |
+
loop = 1
|
| 226 |
+
from_bytes = int.from_bytes
|
| 227 |
+
while len(dkey) < dklen:
|
| 228 |
+
prev = prf(salt + loop.to_bytes(4, 'big'))
|
| 229 |
+
# endianness doesn't matter here as long to / from use the same
|
| 230 |
+
rkey = int.from_bytes(prev, 'big')
|
| 231 |
+
for i in range(iterations - 1):
|
| 232 |
+
prev = prf(prev)
|
| 233 |
+
# rkey = rkey ^ prev
|
| 234 |
+
rkey ^= from_bytes(prev, 'big')
|
| 235 |
+
loop += 1
|
| 236 |
+
dkey += rkey.to_bytes(inner.digest_size, 'big')
|
| 237 |
+
|
| 238 |
+
return dkey[:dklen]
|
| 239 |
+
|
| 240 |
+
try:
|
| 241 |
+
# OpenSSL's scrypt requires OpenSSL 1.1+
|
| 242 |
+
from _hashlib import scrypt
|
| 243 |
+
except ImportError:
|
| 244 |
+
pass
|
| 245 |
+
|
| 246 |
+
|
| 247 |
+
for __func_name in __always_supported:
|
| 248 |
+
# try them all, some may not work due to the OpenSSL
|
| 249 |
+
# version not supporting that algorithm.
|
| 250 |
+
try:
|
| 251 |
+
globals()[__func_name] = __get_hash(__func_name)
|
| 252 |
+
except ValueError:
|
| 253 |
+
import logging
|
| 254 |
+
logging.exception('code for hash %s was not found.', __func_name)
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
# Cleanup locals()
|
| 258 |
+
del __always_supported, __func_name, __get_hash
|
| 259 |
+
del __py_new, __hash_new, __get_openssl_constructor
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/imp.py
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""This module provides the components needed to build your own __import__
|
| 2 |
+
function. Undocumented functions are obsolete.
|
| 3 |
+
|
| 4 |
+
In most cases it is preferred you consider using the importlib module's
|
| 5 |
+
functionality over this module.
|
| 6 |
+
|
| 7 |
+
"""
|
| 8 |
+
# (Probably) need to stay in _imp
|
| 9 |
+
from _imp import (lock_held, acquire_lock, release_lock,
|
| 10 |
+
get_frozen_object, is_frozen_package,
|
| 11 |
+
init_frozen, is_builtin, is_frozen,
|
| 12 |
+
_fix_co_filename)
|
| 13 |
+
try:
|
| 14 |
+
from _imp import create_dynamic
|
| 15 |
+
except ImportError:
|
| 16 |
+
# Platform doesn't support dynamic loading.
|
| 17 |
+
create_dynamic = None
|
| 18 |
+
|
| 19 |
+
from importlib._bootstrap import _ERR_MSG, _exec, _load, _builtin_from_name
|
| 20 |
+
from importlib._bootstrap_external import SourcelessFileLoader
|
| 21 |
+
|
| 22 |
+
from importlib import machinery
|
| 23 |
+
from importlib import util
|
| 24 |
+
import importlib
|
| 25 |
+
import os
|
| 26 |
+
import sys
|
| 27 |
+
import tokenize
|
| 28 |
+
import types
|
| 29 |
+
import warnings
|
| 30 |
+
|
| 31 |
+
warnings.warn("the imp module is deprecated in favour of importlib; "
|
| 32 |
+
"see the module's documentation for alternative uses",
|
| 33 |
+
DeprecationWarning, stacklevel=2)
|
| 34 |
+
|
| 35 |
+
# DEPRECATED
|
| 36 |
+
SEARCH_ERROR = 0
|
| 37 |
+
PY_SOURCE = 1
|
| 38 |
+
PY_COMPILED = 2
|
| 39 |
+
C_EXTENSION = 3
|
| 40 |
+
PY_RESOURCE = 4
|
| 41 |
+
PKG_DIRECTORY = 5
|
| 42 |
+
C_BUILTIN = 6
|
| 43 |
+
PY_FROZEN = 7
|
| 44 |
+
PY_CODERESOURCE = 8
|
| 45 |
+
IMP_HOOK = 9
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def new_module(name):
|
| 49 |
+
"""**DEPRECATED**
|
| 50 |
+
|
| 51 |
+
Create a new module.
|
| 52 |
+
|
| 53 |
+
The module is not entered into sys.modules.
|
| 54 |
+
|
| 55 |
+
"""
|
| 56 |
+
return types.ModuleType(name)
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def get_magic():
|
| 60 |
+
"""**DEPRECATED**
|
| 61 |
+
|
| 62 |
+
Return the magic number for .pyc files.
|
| 63 |
+
"""
|
| 64 |
+
return util.MAGIC_NUMBER
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def get_tag():
|
| 68 |
+
"""Return the magic tag for .pyc files."""
|
| 69 |
+
return sys.implementation.cache_tag
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def cache_from_source(path, debug_override=None):
|
| 73 |
+
"""**DEPRECATED**
|
| 74 |
+
|
| 75 |
+
Given the path to a .py file, return the path to its .pyc file.
|
| 76 |
+
|
| 77 |
+
The .py file does not need to exist; this simply returns the path to the
|
| 78 |
+
.pyc file calculated as if the .py file were imported.
|
| 79 |
+
|
| 80 |
+
If debug_override is not None, then it must be a boolean and is used in
|
| 81 |
+
place of sys.flags.optimize.
|
| 82 |
+
|
| 83 |
+
If sys.implementation.cache_tag is None then NotImplementedError is raised.
|
| 84 |
+
|
| 85 |
+
"""
|
| 86 |
+
with warnings.catch_warnings():
|
| 87 |
+
warnings.simplefilter('ignore')
|
| 88 |
+
return util.cache_from_source(path, debug_override)
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def source_from_cache(path):
|
| 92 |
+
"""**DEPRECATED**
|
| 93 |
+
|
| 94 |
+
Given the path to a .pyc. file, return the path to its .py file.
|
| 95 |
+
|
| 96 |
+
The .pyc file does not need to exist; this simply returns the path to
|
| 97 |
+
the .py file calculated to correspond to the .pyc file. If path does
|
| 98 |
+
not conform to PEP 3147 format, ValueError will be raised. If
|
| 99 |
+
sys.implementation.cache_tag is None then NotImplementedError is raised.
|
| 100 |
+
|
| 101 |
+
"""
|
| 102 |
+
return util.source_from_cache(path)
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
def get_suffixes():
|
| 106 |
+
"""**DEPRECATED**"""
|
| 107 |
+
extensions = [(s, 'rb', C_EXTENSION) for s in machinery.EXTENSION_SUFFIXES]
|
| 108 |
+
source = [(s, 'r', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES]
|
| 109 |
+
bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES]
|
| 110 |
+
|
| 111 |
+
return extensions + source + bytecode
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
class NullImporter:
|
| 115 |
+
|
| 116 |
+
"""**DEPRECATED**
|
| 117 |
+
|
| 118 |
+
Null import object.
|
| 119 |
+
|
| 120 |
+
"""
|
| 121 |
+
|
| 122 |
+
def __init__(self, path):
|
| 123 |
+
if path == '':
|
| 124 |
+
raise ImportError('empty pathname', path='')
|
| 125 |
+
elif os.path.isdir(path):
|
| 126 |
+
raise ImportError('existing directory', path=path)
|
| 127 |
+
|
| 128 |
+
def find_module(self, fullname):
|
| 129 |
+
"""Always returns None."""
|
| 130 |
+
return None
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
class _HackedGetData:
|
| 134 |
+
|
| 135 |
+
"""Compatibility support for 'file' arguments of various load_*()
|
| 136 |
+
functions."""
|
| 137 |
+
|
| 138 |
+
def __init__(self, fullname, path, file=None):
|
| 139 |
+
super().__init__(fullname, path)
|
| 140 |
+
self.file = file
|
| 141 |
+
|
| 142 |
+
def get_data(self, path):
|
| 143 |
+
"""Gross hack to contort loader to deal w/ load_*()'s bad API."""
|
| 144 |
+
if self.file and path == self.path:
|
| 145 |
+
# The contract of get_data() requires us to return bytes. Reopen the
|
| 146 |
+
# file in binary mode if needed.
|
| 147 |
+
if not self.file.closed:
|
| 148 |
+
file = self.file
|
| 149 |
+
if 'b' not in file.mode:
|
| 150 |
+
file.close()
|
| 151 |
+
if self.file.closed:
|
| 152 |
+
self.file = file = open(self.path, 'rb')
|
| 153 |
+
|
| 154 |
+
with file:
|
| 155 |
+
return file.read()
|
| 156 |
+
else:
|
| 157 |
+
return super().get_data(path)
|
| 158 |
+
|
| 159 |
+
|
| 160 |
+
class _LoadSourceCompatibility(_HackedGetData, machinery.SourceFileLoader):
|
| 161 |
+
|
| 162 |
+
"""Compatibility support for implementing load_source()."""
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
def load_source(name, pathname, file=None):
|
| 166 |
+
loader = _LoadSourceCompatibility(name, pathname, file)
|
| 167 |
+
spec = util.spec_from_file_location(name, pathname, loader=loader)
|
| 168 |
+
if name in sys.modules:
|
| 169 |
+
module = _exec(spec, sys.modules[name])
|
| 170 |
+
else:
|
| 171 |
+
module = _load(spec)
|
| 172 |
+
# To allow reloading to potentially work, use a non-hacked loader which
|
| 173 |
+
# won't rely on a now-closed file object.
|
| 174 |
+
module.__loader__ = machinery.SourceFileLoader(name, pathname)
|
| 175 |
+
module.__spec__.loader = module.__loader__
|
| 176 |
+
return module
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
class _LoadCompiledCompatibility(_HackedGetData, SourcelessFileLoader):
|
| 180 |
+
|
| 181 |
+
"""Compatibility support for implementing load_compiled()."""
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
def load_compiled(name, pathname, file=None):
|
| 185 |
+
"""**DEPRECATED**"""
|
| 186 |
+
loader = _LoadCompiledCompatibility(name, pathname, file)
|
| 187 |
+
spec = util.spec_from_file_location(name, pathname, loader=loader)
|
| 188 |
+
if name in sys.modules:
|
| 189 |
+
module = _exec(spec, sys.modules[name])
|
| 190 |
+
else:
|
| 191 |
+
module = _load(spec)
|
| 192 |
+
# To allow reloading to potentially work, use a non-hacked loader which
|
| 193 |
+
# won't rely on a now-closed file object.
|
| 194 |
+
module.__loader__ = SourcelessFileLoader(name, pathname)
|
| 195 |
+
module.__spec__.loader = module.__loader__
|
| 196 |
+
return module
|
| 197 |
+
|
| 198 |
+
|
| 199 |
+
def load_package(name, path):
|
| 200 |
+
"""**DEPRECATED**"""
|
| 201 |
+
if os.path.isdir(path):
|
| 202 |
+
extensions = (machinery.SOURCE_SUFFIXES[:] +
|
| 203 |
+
machinery.BYTECODE_SUFFIXES[:])
|
| 204 |
+
for extension in extensions:
|
| 205 |
+
init_path = os.path.join(path, '__init__' + extension)
|
| 206 |
+
if os.path.exists(init_path):
|
| 207 |
+
path = init_path
|
| 208 |
+
break
|
| 209 |
+
else:
|
| 210 |
+
raise ValueError('{!r} is not a package'.format(path))
|
| 211 |
+
spec = util.spec_from_file_location(name, path,
|
| 212 |
+
submodule_search_locations=[])
|
| 213 |
+
if name in sys.modules:
|
| 214 |
+
return _exec(spec, sys.modules[name])
|
| 215 |
+
else:
|
| 216 |
+
return _load(spec)
|
| 217 |
+
|
| 218 |
+
|
| 219 |
+
def load_module(name, file, filename, details):
|
| 220 |
+
"""**DEPRECATED**
|
| 221 |
+
|
| 222 |
+
Load a module, given information returned by find_module().
|
| 223 |
+
|
| 224 |
+
The module name must include the full package name, if any.
|
| 225 |
+
|
| 226 |
+
"""
|
| 227 |
+
suffix, mode, type_ = details
|
| 228 |
+
if mode and (not mode.startswith(('r', 'U')) or '+' in mode):
|
| 229 |
+
raise ValueError('invalid file open mode {!r}'.format(mode))
|
| 230 |
+
elif file is None and type_ in {PY_SOURCE, PY_COMPILED}:
|
| 231 |
+
msg = 'file object required for import (type code {})'.format(type_)
|
| 232 |
+
raise ValueError(msg)
|
| 233 |
+
elif type_ == PY_SOURCE:
|
| 234 |
+
return load_source(name, filename, file)
|
| 235 |
+
elif type_ == PY_COMPILED:
|
| 236 |
+
return load_compiled(name, filename, file)
|
| 237 |
+
elif type_ == C_EXTENSION and load_dynamic is not None:
|
| 238 |
+
if file is None:
|
| 239 |
+
with open(filename, 'rb') as opened_file:
|
| 240 |
+
return load_dynamic(name, filename, opened_file)
|
| 241 |
+
else:
|
| 242 |
+
return load_dynamic(name, filename, file)
|
| 243 |
+
elif type_ == PKG_DIRECTORY:
|
| 244 |
+
return load_package(name, filename)
|
| 245 |
+
elif type_ == C_BUILTIN:
|
| 246 |
+
return init_builtin(name)
|
| 247 |
+
elif type_ == PY_FROZEN:
|
| 248 |
+
return init_frozen(name)
|
| 249 |
+
else:
|
| 250 |
+
msg = "Don't know how to import {} (type code {})".format(name, type_)
|
| 251 |
+
raise ImportError(msg, name=name)
|
| 252 |
+
|
| 253 |
+
|
| 254 |
+
def find_module(name, path=None):
|
| 255 |
+
"""**DEPRECATED**
|
| 256 |
+
|
| 257 |
+
Search for a module.
|
| 258 |
+
|
| 259 |
+
If path is omitted or None, search for a built-in, frozen or special
|
| 260 |
+
module and continue search in sys.path. The module name cannot
|
| 261 |
+
contain '.'; to search for a submodule of a package, pass the
|
| 262 |
+
submodule name and the package's __path__.
|
| 263 |
+
|
| 264 |
+
"""
|
| 265 |
+
if not isinstance(name, str):
|
| 266 |
+
raise TypeError("'name' must be a str, not {}".format(type(name)))
|
| 267 |
+
elif not isinstance(path, (type(None), list)):
|
| 268 |
+
# Backwards-compatibility
|
| 269 |
+
raise RuntimeError("'path' must be None or a list, "
|
| 270 |
+
"not {}".format(type(path)))
|
| 271 |
+
|
| 272 |
+
if path is None:
|
| 273 |
+
if is_builtin(name):
|
| 274 |
+
return None, None, ('', '', C_BUILTIN)
|
| 275 |
+
elif is_frozen(name):
|
| 276 |
+
return None, None, ('', '', PY_FROZEN)
|
| 277 |
+
else:
|
| 278 |
+
path = sys.path
|
| 279 |
+
|
| 280 |
+
for entry in path:
|
| 281 |
+
package_directory = os.path.join(entry, name)
|
| 282 |
+
for suffix in ['.py', machinery.BYTECODE_SUFFIXES[0]]:
|
| 283 |
+
package_file_name = '__init__' + suffix
|
| 284 |
+
file_path = os.path.join(package_directory, package_file_name)
|
| 285 |
+
if os.path.isfile(file_path):
|
| 286 |
+
return None, package_directory, ('', '', PKG_DIRECTORY)
|
| 287 |
+
for suffix, mode, type_ in get_suffixes():
|
| 288 |
+
file_name = name + suffix
|
| 289 |
+
file_path = os.path.join(entry, file_name)
|
| 290 |
+
if os.path.isfile(file_path):
|
| 291 |
+
break
|
| 292 |
+
else:
|
| 293 |
+
continue
|
| 294 |
+
break # Break out of outer loop when breaking out of inner loop.
|
| 295 |
+
else:
|
| 296 |
+
raise ImportError(_ERR_MSG.format(name), name=name)
|
| 297 |
+
|
| 298 |
+
encoding = None
|
| 299 |
+
if 'b' not in mode:
|
| 300 |
+
with open(file_path, 'rb') as file:
|
| 301 |
+
encoding = tokenize.detect_encoding(file.readline)[0]
|
| 302 |
+
file = open(file_path, mode, encoding=encoding)
|
| 303 |
+
return file, file_path, (suffix, mode, type_)
|
| 304 |
+
|
| 305 |
+
|
| 306 |
+
def reload(module):
|
| 307 |
+
"""**DEPRECATED**
|
| 308 |
+
|
| 309 |
+
Reload the module and return it.
|
| 310 |
+
|
| 311 |
+
The module must have been successfully imported before.
|
| 312 |
+
|
| 313 |
+
"""
|
| 314 |
+
return importlib.reload(module)
|
| 315 |
+
|
| 316 |
+
|
| 317 |
+
def init_builtin(name):
|
| 318 |
+
"""**DEPRECATED**
|
| 319 |
+
|
| 320 |
+
Load and return a built-in module by name, or None is such module doesn't
|
| 321 |
+
exist
|
| 322 |
+
"""
|
| 323 |
+
try:
|
| 324 |
+
return _builtin_from_name(name)
|
| 325 |
+
except ImportError:
|
| 326 |
+
return None
|
| 327 |
+
|
| 328 |
+
|
| 329 |
+
if create_dynamic:
|
| 330 |
+
def load_dynamic(name, path, file=None):
|
| 331 |
+
"""**DEPRECATED**
|
| 332 |
+
|
| 333 |
+
Load an extension module.
|
| 334 |
+
"""
|
| 335 |
+
import importlib.machinery
|
| 336 |
+
loader = importlib.machinery.ExtensionFileLoader(name, path)
|
| 337 |
+
|
| 338 |
+
# Issue #24748: Skip the sys.modules check in _load_module_shim;
|
| 339 |
+
# always load new extension
|
| 340 |
+
spec = importlib.machinery.ModuleSpec(
|
| 341 |
+
name=name, loader=loader, origin=path)
|
| 342 |
+
return _load(spec)
|
| 343 |
+
|
| 344 |
+
else:
|
| 345 |
+
load_dynamic = None
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/inspect.py
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/io.py
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""The io module provides the Python interfaces to stream handling. The
|
| 2 |
+
builtin open function is defined in this module.
|
| 3 |
+
|
| 4 |
+
At the top of the I/O hierarchy is the abstract base class IOBase. It
|
| 5 |
+
defines the basic interface to a stream. Note, however, that there is no
|
| 6 |
+
separation between reading and writing to streams; implementations are
|
| 7 |
+
allowed to raise an OSError if they do not support a given operation.
|
| 8 |
+
|
| 9 |
+
Extending IOBase is RawIOBase which deals simply with the reading and
|
| 10 |
+
writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide
|
| 11 |
+
an interface to OS files.
|
| 12 |
+
|
| 13 |
+
BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its
|
| 14 |
+
subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer
|
| 15 |
+
streams that are readable, writable, and both respectively.
|
| 16 |
+
BufferedRandom provides a buffered interface to random access
|
| 17 |
+
streams. BytesIO is a simple stream of in-memory bytes.
|
| 18 |
+
|
| 19 |
+
Another IOBase subclass, TextIOBase, deals with the encoding and decoding
|
| 20 |
+
of streams into text. TextIOWrapper, which extends it, is a buffered text
|
| 21 |
+
interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO
|
| 22 |
+
is an in-memory stream for text.
|
| 23 |
+
|
| 24 |
+
Argument names are not part of the specification, and only the arguments
|
| 25 |
+
of open() are intended to be used as keyword arguments.
|
| 26 |
+
|
| 27 |
+
data:
|
| 28 |
+
|
| 29 |
+
DEFAULT_BUFFER_SIZE
|
| 30 |
+
|
| 31 |
+
An int containing the default buffer size used by the module's buffered
|
| 32 |
+
I/O classes. open() uses the file's blksize (as obtained by os.stat) if
|
| 33 |
+
possible.
|
| 34 |
+
"""
|
| 35 |
+
# New I/O library conforming to PEP 3116.
|
| 36 |
+
|
| 37 |
+
__author__ = ("Guido van Rossum <guido@python.org>, "
|
| 38 |
+
"Mike Verdone <mike.verdone@gmail.com>, "
|
| 39 |
+
"Mark Russell <mark.russell@zen.co.uk>, "
|
| 40 |
+
"Antoine Pitrou <solipsis@pitrou.net>, "
|
| 41 |
+
"Amaury Forgeot d'Arc <amauryfa@gmail.com>, "
|
| 42 |
+
"Benjamin Peterson <benjamin@python.org>")
|
| 43 |
+
|
| 44 |
+
__all__ = ["BlockingIOError", "open", "open_code", "IOBase", "RawIOBase",
|
| 45 |
+
"FileIO", "BytesIO", "StringIO", "BufferedIOBase",
|
| 46 |
+
"BufferedReader", "BufferedWriter", "BufferedRWPair",
|
| 47 |
+
"BufferedRandom", "TextIOBase", "TextIOWrapper",
|
| 48 |
+
"UnsupportedOperation", "SEEK_SET", "SEEK_CUR", "SEEK_END"]
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
import _io
|
| 52 |
+
import abc
|
| 53 |
+
|
| 54 |
+
from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation,
|
| 55 |
+
open, open_code, FileIO, BytesIO, StringIO, BufferedReader,
|
| 56 |
+
BufferedWriter, BufferedRWPair, BufferedRandom,
|
| 57 |
+
IncrementalNewlineDecoder, TextIOWrapper)
|
| 58 |
+
|
| 59 |
+
OpenWrapper = _io.open # for compatibility with _pyio
|
| 60 |
+
|
| 61 |
+
# Pretend this exception was created here.
|
| 62 |
+
UnsupportedOperation.__module__ = "io"
|
| 63 |
+
|
| 64 |
+
# for seek()
|
| 65 |
+
SEEK_SET = 0
|
| 66 |
+
SEEK_CUR = 1
|
| 67 |
+
SEEK_END = 2
|
| 68 |
+
|
| 69 |
+
# Declaring ABCs in C is tricky so we do it here.
|
| 70 |
+
# Method descriptions and default implementations are inherited from the C
|
| 71 |
+
# version however.
|
| 72 |
+
class IOBase(_io._IOBase, metaclass=abc.ABCMeta):
|
| 73 |
+
__doc__ = _io._IOBase.__doc__
|
| 74 |
+
|
| 75 |
+
class RawIOBase(_io._RawIOBase, IOBase):
|
| 76 |
+
__doc__ = _io._RawIOBase.__doc__
|
| 77 |
+
|
| 78 |
+
class BufferedIOBase(_io._BufferedIOBase, IOBase):
|
| 79 |
+
__doc__ = _io._BufferedIOBase.__doc__
|
| 80 |
+
|
| 81 |
+
class TextIOBase(_io._TextIOBase, IOBase):
|
| 82 |
+
__doc__ = _io._TextIOBase.__doc__
|
| 83 |
+
|
| 84 |
+
RawIOBase.register(FileIO)
|
| 85 |
+
|
| 86 |
+
for klass in (BytesIO, BufferedReader, BufferedWriter, BufferedRandom,
|
| 87 |
+
BufferedRWPair):
|
| 88 |
+
BufferedIOBase.register(klass)
|
| 89 |
+
|
| 90 |
+
for klass in (StringIO, TextIOWrapper):
|
| 91 |
+
TextIOBase.register(klass)
|
| 92 |
+
del klass
|
| 93 |
+
|
| 94 |
+
try:
|
| 95 |
+
from _io import _WindowsConsoleIO
|
| 96 |
+
except ImportError:
|
| 97 |
+
pass
|
| 98 |
+
else:
|
| 99 |
+
RawIOBase.register(_WindowsConsoleIO)
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/lzma.py
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Interface to the liblzma compression library.
|
| 2 |
+
|
| 3 |
+
This module provides a class for reading and writing compressed files,
|
| 4 |
+
classes for incremental (de)compression, and convenience functions for
|
| 5 |
+
one-shot (de)compression.
|
| 6 |
+
|
| 7 |
+
These classes and functions support both the XZ and legacy LZMA
|
| 8 |
+
container formats, as well as raw compressed data streams.
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
__all__ = [
|
| 12 |
+
"CHECK_NONE", "CHECK_CRC32", "CHECK_CRC64", "CHECK_SHA256",
|
| 13 |
+
"CHECK_ID_MAX", "CHECK_UNKNOWN",
|
| 14 |
+
"FILTER_LZMA1", "FILTER_LZMA2", "FILTER_DELTA", "FILTER_X86", "FILTER_IA64",
|
| 15 |
+
"FILTER_ARM", "FILTER_ARMTHUMB", "FILTER_POWERPC", "FILTER_SPARC",
|
| 16 |
+
"FORMAT_AUTO", "FORMAT_XZ", "FORMAT_ALONE", "FORMAT_RAW",
|
| 17 |
+
"MF_HC3", "MF_HC4", "MF_BT2", "MF_BT3", "MF_BT4",
|
| 18 |
+
"MODE_FAST", "MODE_NORMAL", "PRESET_DEFAULT", "PRESET_EXTREME",
|
| 19 |
+
|
| 20 |
+
"LZMACompressor", "LZMADecompressor", "LZMAFile", "LZMAError",
|
| 21 |
+
"open", "compress", "decompress", "is_check_supported",
|
| 22 |
+
]
|
| 23 |
+
|
| 24 |
+
import builtins
|
| 25 |
+
import io
|
| 26 |
+
import os
|
| 27 |
+
from _lzma import *
|
| 28 |
+
from _lzma import _encode_filter_properties, _decode_filter_properties
|
| 29 |
+
import _compression
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
_MODE_CLOSED = 0
|
| 33 |
+
_MODE_READ = 1
|
| 34 |
+
# Value 2 no longer used
|
| 35 |
+
_MODE_WRITE = 3
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
class LZMAFile(_compression.BaseStream):
|
| 39 |
+
|
| 40 |
+
"""A file object providing transparent LZMA (de)compression.
|
| 41 |
+
|
| 42 |
+
An LZMAFile can act as a wrapper for an existing file object, or
|
| 43 |
+
refer directly to a named file on disk.
|
| 44 |
+
|
| 45 |
+
Note that LZMAFile provides a *binary* file interface - data read
|
| 46 |
+
is returned as bytes, and data to be written must be given as bytes.
|
| 47 |
+
"""
|
| 48 |
+
|
| 49 |
+
def __init__(self, filename=None, mode="r", *,
|
| 50 |
+
format=None, check=-1, preset=None, filters=None):
|
| 51 |
+
"""Open an LZMA-compressed file in binary mode.
|
| 52 |
+
|
| 53 |
+
filename can be either an actual file name (given as a str,
|
| 54 |
+
bytes, or PathLike object), in which case the named file is
|
| 55 |
+
opened, or it can be an existing file object to read from or
|
| 56 |
+
write to.
|
| 57 |
+
|
| 58 |
+
mode can be "r" for reading (default), "w" for (over)writing,
|
| 59 |
+
"x" for creating exclusively, or "a" for appending. These can
|
| 60 |
+
equivalently be given as "rb", "wb", "xb" and "ab" respectively.
|
| 61 |
+
|
| 62 |
+
format specifies the container format to use for the file.
|
| 63 |
+
If mode is "r", this defaults to FORMAT_AUTO. Otherwise, the
|
| 64 |
+
default is FORMAT_XZ.
|
| 65 |
+
|
| 66 |
+
check specifies the integrity check to use. This argument can
|
| 67 |
+
only be used when opening a file for writing. For FORMAT_XZ,
|
| 68 |
+
the default is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not
|
| 69 |
+
support integrity checks - for these formats, check must be
|
| 70 |
+
omitted, or be CHECK_NONE.
|
| 71 |
+
|
| 72 |
+
When opening a file for reading, the *preset* argument is not
|
| 73 |
+
meaningful, and should be omitted. The *filters* argument should
|
| 74 |
+
also be omitted, except when format is FORMAT_RAW (in which case
|
| 75 |
+
it is required).
|
| 76 |
+
|
| 77 |
+
When opening a file for writing, the settings used by the
|
| 78 |
+
compressor can be specified either as a preset compression
|
| 79 |
+
level (with the *preset* argument), or in detail as a custom
|
| 80 |
+
filter chain (with the *filters* argument). For FORMAT_XZ and
|
| 81 |
+
FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset
|
| 82 |
+
level. For FORMAT_RAW, the caller must always specify a filter
|
| 83 |
+
chain; the raw compressor does not support preset compression
|
| 84 |
+
levels.
|
| 85 |
+
|
| 86 |
+
preset (if provided) should be an integer in the range 0-9,
|
| 87 |
+
optionally OR-ed with the constant PRESET_EXTREME.
|
| 88 |
+
|
| 89 |
+
filters (if provided) should be a sequence of dicts. Each dict
|
| 90 |
+
should have an entry for "id" indicating ID of the filter, plus
|
| 91 |
+
additional entries for options to the filter.
|
| 92 |
+
"""
|
| 93 |
+
self._fp = None
|
| 94 |
+
self._closefp = False
|
| 95 |
+
self._mode = _MODE_CLOSED
|
| 96 |
+
|
| 97 |
+
if mode in ("r", "rb"):
|
| 98 |
+
if check != -1:
|
| 99 |
+
raise ValueError("Cannot specify an integrity check "
|
| 100 |
+
"when opening a file for reading")
|
| 101 |
+
if preset is not None:
|
| 102 |
+
raise ValueError("Cannot specify a preset compression "
|
| 103 |
+
"level when opening a file for reading")
|
| 104 |
+
if format is None:
|
| 105 |
+
format = FORMAT_AUTO
|
| 106 |
+
mode_code = _MODE_READ
|
| 107 |
+
elif mode in ("w", "wb", "a", "ab", "x", "xb"):
|
| 108 |
+
if format is None:
|
| 109 |
+
format = FORMAT_XZ
|
| 110 |
+
mode_code = _MODE_WRITE
|
| 111 |
+
self._compressor = LZMACompressor(format=format, check=check,
|
| 112 |
+
preset=preset, filters=filters)
|
| 113 |
+
self._pos = 0
|
| 114 |
+
else:
|
| 115 |
+
raise ValueError("Invalid mode: {!r}".format(mode))
|
| 116 |
+
|
| 117 |
+
if isinstance(filename, (str, bytes, os.PathLike)):
|
| 118 |
+
if "b" not in mode:
|
| 119 |
+
mode += "b"
|
| 120 |
+
self._fp = builtins.open(filename, mode)
|
| 121 |
+
self._closefp = True
|
| 122 |
+
self._mode = mode_code
|
| 123 |
+
elif hasattr(filename, "read") or hasattr(filename, "write"):
|
| 124 |
+
self._fp = filename
|
| 125 |
+
self._mode = mode_code
|
| 126 |
+
else:
|
| 127 |
+
raise TypeError("filename must be a str, bytes, file or PathLike object")
|
| 128 |
+
|
| 129 |
+
if self._mode == _MODE_READ:
|
| 130 |
+
raw = _compression.DecompressReader(self._fp, LZMADecompressor,
|
| 131 |
+
trailing_error=LZMAError, format=format, filters=filters)
|
| 132 |
+
self._buffer = io.BufferedReader(raw)
|
| 133 |
+
|
| 134 |
+
def close(self):
|
| 135 |
+
"""Flush and close the file.
|
| 136 |
+
|
| 137 |
+
May be called more than once without error. Once the file is
|
| 138 |
+
closed, any other operation on it will raise a ValueError.
|
| 139 |
+
"""
|
| 140 |
+
if self._mode == _MODE_CLOSED:
|
| 141 |
+
return
|
| 142 |
+
try:
|
| 143 |
+
if self._mode == _MODE_READ:
|
| 144 |
+
self._buffer.close()
|
| 145 |
+
self._buffer = None
|
| 146 |
+
elif self._mode == _MODE_WRITE:
|
| 147 |
+
self._fp.write(self._compressor.flush())
|
| 148 |
+
self._compressor = None
|
| 149 |
+
finally:
|
| 150 |
+
try:
|
| 151 |
+
if self._closefp:
|
| 152 |
+
self._fp.close()
|
| 153 |
+
finally:
|
| 154 |
+
self._fp = None
|
| 155 |
+
self._closefp = False
|
| 156 |
+
self._mode = _MODE_CLOSED
|
| 157 |
+
|
| 158 |
+
@property
|
| 159 |
+
def closed(self):
|
| 160 |
+
"""True if this file is closed."""
|
| 161 |
+
return self._mode == _MODE_CLOSED
|
| 162 |
+
|
| 163 |
+
def fileno(self):
|
| 164 |
+
"""Return the file descriptor for the underlying file."""
|
| 165 |
+
self._check_not_closed()
|
| 166 |
+
return self._fp.fileno()
|
| 167 |
+
|
| 168 |
+
def seekable(self):
|
| 169 |
+
"""Return whether the file supports seeking."""
|
| 170 |
+
return self.readable() and self._buffer.seekable()
|
| 171 |
+
|
| 172 |
+
def readable(self):
|
| 173 |
+
"""Return whether the file was opened for reading."""
|
| 174 |
+
self._check_not_closed()
|
| 175 |
+
return self._mode == _MODE_READ
|
| 176 |
+
|
| 177 |
+
def writable(self):
|
| 178 |
+
"""Return whether the file was opened for writing."""
|
| 179 |
+
self._check_not_closed()
|
| 180 |
+
return self._mode == _MODE_WRITE
|
| 181 |
+
|
| 182 |
+
def peek(self, size=-1):
|
| 183 |
+
"""Return buffered data without advancing the file position.
|
| 184 |
+
|
| 185 |
+
Always returns at least one byte of data, unless at EOF.
|
| 186 |
+
The exact number of bytes returned is unspecified.
|
| 187 |
+
"""
|
| 188 |
+
self._check_can_read()
|
| 189 |
+
# Relies on the undocumented fact that BufferedReader.peek() always
|
| 190 |
+
# returns at least one byte (except at EOF)
|
| 191 |
+
return self._buffer.peek(size)
|
| 192 |
+
|
| 193 |
+
def read(self, size=-1):
|
| 194 |
+
"""Read up to size uncompressed bytes from the file.
|
| 195 |
+
|
| 196 |
+
If size is negative or omitted, read until EOF is reached.
|
| 197 |
+
Returns b"" if the file is already at EOF.
|
| 198 |
+
"""
|
| 199 |
+
self._check_can_read()
|
| 200 |
+
return self._buffer.read(size)
|
| 201 |
+
|
| 202 |
+
def read1(self, size=-1):
|
| 203 |
+
"""Read up to size uncompressed bytes, while trying to avoid
|
| 204 |
+
making multiple reads from the underlying stream. Reads up to a
|
| 205 |
+
buffer's worth of data if size is negative.
|
| 206 |
+
|
| 207 |
+
Returns b"" if the file is at EOF.
|
| 208 |
+
"""
|
| 209 |
+
self._check_can_read()
|
| 210 |
+
if size < 0:
|
| 211 |
+
size = io.DEFAULT_BUFFER_SIZE
|
| 212 |
+
return self._buffer.read1(size)
|
| 213 |
+
|
| 214 |
+
def readline(self, size=-1):
|
| 215 |
+
"""Read a line of uncompressed bytes from the file.
|
| 216 |
+
|
| 217 |
+
The terminating newline (if present) is retained. If size is
|
| 218 |
+
non-negative, no more than size bytes will be read (in which
|
| 219 |
+
case the line may be incomplete). Returns b'' if already at EOF.
|
| 220 |
+
"""
|
| 221 |
+
self._check_can_read()
|
| 222 |
+
return self._buffer.readline(size)
|
| 223 |
+
|
| 224 |
+
def write(self, data):
|
| 225 |
+
"""Write a bytes object to the file.
|
| 226 |
+
|
| 227 |
+
Returns the number of uncompressed bytes written, which is
|
| 228 |
+
always len(data). Note that due to buffering, the file on disk
|
| 229 |
+
may not reflect the data written until close() is called.
|
| 230 |
+
"""
|
| 231 |
+
self._check_can_write()
|
| 232 |
+
compressed = self._compressor.compress(data)
|
| 233 |
+
self._fp.write(compressed)
|
| 234 |
+
self._pos += len(data)
|
| 235 |
+
return len(data)
|
| 236 |
+
|
| 237 |
+
def seek(self, offset, whence=io.SEEK_SET):
|
| 238 |
+
"""Change the file position.
|
| 239 |
+
|
| 240 |
+
The new position is specified by offset, relative to the
|
| 241 |
+
position indicated by whence. Possible values for whence are:
|
| 242 |
+
|
| 243 |
+
0: start of stream (default): offset must not be negative
|
| 244 |
+
1: current stream position
|
| 245 |
+
2: end of stream; offset must not be positive
|
| 246 |
+
|
| 247 |
+
Returns the new file position.
|
| 248 |
+
|
| 249 |
+
Note that seeking is emulated, so depending on the parameters,
|
| 250 |
+
this operation may be extremely slow.
|
| 251 |
+
"""
|
| 252 |
+
self._check_can_seek()
|
| 253 |
+
return self._buffer.seek(offset, whence)
|
| 254 |
+
|
| 255 |
+
def tell(self):
|
| 256 |
+
"""Return the current file position."""
|
| 257 |
+
self._check_not_closed()
|
| 258 |
+
if self._mode == _MODE_READ:
|
| 259 |
+
return self._buffer.tell()
|
| 260 |
+
return self._pos
|
| 261 |
+
|
| 262 |
+
|
| 263 |
+
def open(filename, mode="rb", *,
|
| 264 |
+
format=None, check=-1, preset=None, filters=None,
|
| 265 |
+
encoding=None, errors=None, newline=None):
|
| 266 |
+
"""Open an LZMA-compressed file in binary or text mode.
|
| 267 |
+
|
| 268 |
+
filename can be either an actual file name (given as a str, bytes,
|
| 269 |
+
or PathLike object), in which case the named file is opened, or it
|
| 270 |
+
can be an existing file object to read from or write to.
|
| 271 |
+
|
| 272 |
+
The mode argument can be "r", "rb" (default), "w", "wb", "x", "xb",
|
| 273 |
+
"a", or "ab" for binary mode, or "rt", "wt", "xt", or "at" for text
|
| 274 |
+
mode.
|
| 275 |
+
|
| 276 |
+
The format, check, preset and filters arguments specify the
|
| 277 |
+
compression settings, as for LZMACompressor, LZMADecompressor and
|
| 278 |
+
LZMAFile.
|
| 279 |
+
|
| 280 |
+
For binary mode, this function is equivalent to the LZMAFile
|
| 281 |
+
constructor: LZMAFile(filename, mode, ...). In this case, the
|
| 282 |
+
encoding, errors and newline arguments must not be provided.
|
| 283 |
+
|
| 284 |
+
For text mode, an LZMAFile object is created, and wrapped in an
|
| 285 |
+
io.TextIOWrapper instance with the specified encoding, error
|
| 286 |
+
handling behavior, and line ending(s).
|
| 287 |
+
|
| 288 |
+
"""
|
| 289 |
+
if "t" in mode:
|
| 290 |
+
if "b" in mode:
|
| 291 |
+
raise ValueError("Invalid mode: %r" % (mode,))
|
| 292 |
+
else:
|
| 293 |
+
if encoding is not None:
|
| 294 |
+
raise ValueError("Argument 'encoding' not supported in binary mode")
|
| 295 |
+
if errors is not None:
|
| 296 |
+
raise ValueError("Argument 'errors' not supported in binary mode")
|
| 297 |
+
if newline is not None:
|
| 298 |
+
raise ValueError("Argument 'newline' not supported in binary mode")
|
| 299 |
+
|
| 300 |
+
lz_mode = mode.replace("t", "")
|
| 301 |
+
binary_file = LZMAFile(filename, lz_mode, format=format, check=check,
|
| 302 |
+
preset=preset, filters=filters)
|
| 303 |
+
|
| 304 |
+
if "t" in mode:
|
| 305 |
+
return io.TextIOWrapper(binary_file, encoding, errors, newline)
|
| 306 |
+
else:
|
| 307 |
+
return binary_file
|
| 308 |
+
|
| 309 |
+
|
| 310 |
+
def compress(data, format=FORMAT_XZ, check=-1, preset=None, filters=None):
|
| 311 |
+
"""Compress a block of data.
|
| 312 |
+
|
| 313 |
+
Refer to LZMACompressor's docstring for a description of the
|
| 314 |
+
optional arguments *format*, *check*, *preset* and *filters*.
|
| 315 |
+
|
| 316 |
+
For incremental compression, use an LZMACompressor instead.
|
| 317 |
+
"""
|
| 318 |
+
comp = LZMACompressor(format, check, preset, filters)
|
| 319 |
+
return comp.compress(data) + comp.flush()
|
| 320 |
+
|
| 321 |
+
|
| 322 |
+
def decompress(data, format=FORMAT_AUTO, memlimit=None, filters=None):
|
| 323 |
+
"""Decompress a block of data.
|
| 324 |
+
|
| 325 |
+
Refer to LZMADecompressor's docstring for a description of the
|
| 326 |
+
optional arguments *format*, *check* and *filters*.
|
| 327 |
+
|
| 328 |
+
For incremental decompression, use an LZMADecompressor instead.
|
| 329 |
+
"""
|
| 330 |
+
results = []
|
| 331 |
+
while True:
|
| 332 |
+
decomp = LZMADecompressor(format, memlimit, filters)
|
| 333 |
+
try:
|
| 334 |
+
res = decomp.decompress(data)
|
| 335 |
+
except LZMAError:
|
| 336 |
+
if results:
|
| 337 |
+
break # Leftover data is not a valid LZMA/XZ stream; ignore it.
|
| 338 |
+
else:
|
| 339 |
+
raise # Error on the first iteration; bail out.
|
| 340 |
+
results.append(res)
|
| 341 |
+
if not decomp.eof:
|
| 342 |
+
raise LZMAError("Compressed data ended before the "
|
| 343 |
+
"end-of-stream marker was reached")
|
| 344 |
+
data = decomp.unused_data
|
| 345 |
+
if not data:
|
| 346 |
+
break
|
| 347 |
+
return b"".join(results)
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/mailbox.py
ADDED
|
@@ -0,0 +1,2146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Read/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes."""
|
| 2 |
+
|
| 3 |
+
# Notes for authors of new mailbox subclasses:
|
| 4 |
+
#
|
| 5 |
+
# Remember to fsync() changes to disk before closing a modified file
|
| 6 |
+
# or returning from a flush() method. See functions _sync_flush() and
|
| 7 |
+
# _sync_close().
|
| 8 |
+
|
| 9 |
+
import os
|
| 10 |
+
import time
|
| 11 |
+
import calendar
|
| 12 |
+
import socket
|
| 13 |
+
import errno
|
| 14 |
+
import copy
|
| 15 |
+
import warnings
|
| 16 |
+
import email
|
| 17 |
+
import email.message
|
| 18 |
+
import email.generator
|
| 19 |
+
import io
|
| 20 |
+
import contextlib
|
| 21 |
+
try:
|
| 22 |
+
import fcntl
|
| 23 |
+
except ImportError:
|
| 24 |
+
fcntl = None
|
| 25 |
+
|
| 26 |
+
__all__ = ['Mailbox', 'Maildir', 'mbox', 'MH', 'Babyl', 'MMDF',
|
| 27 |
+
'Message', 'MaildirMessage', 'mboxMessage', 'MHMessage',
|
| 28 |
+
'BabylMessage', 'MMDFMessage', 'Error', 'NoSuchMailboxError',
|
| 29 |
+
'NotEmptyError', 'ExternalClashError', 'FormatError']
|
| 30 |
+
|
| 31 |
+
linesep = os.linesep.encode('ascii')
|
| 32 |
+
|
| 33 |
+
class Mailbox:
|
| 34 |
+
"""A group of messages in a particular place."""
|
| 35 |
+
|
| 36 |
+
def __init__(self, path, factory=None, create=True):
|
| 37 |
+
"""Initialize a Mailbox instance."""
|
| 38 |
+
self._path = os.path.abspath(os.path.expanduser(path))
|
| 39 |
+
self._factory = factory
|
| 40 |
+
|
| 41 |
+
def add(self, message):
|
| 42 |
+
"""Add message and return assigned key."""
|
| 43 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 44 |
+
|
| 45 |
+
def remove(self, key):
|
| 46 |
+
"""Remove the keyed message; raise KeyError if it doesn't exist."""
|
| 47 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 48 |
+
|
| 49 |
+
def __delitem__(self, key):
|
| 50 |
+
self.remove(key)
|
| 51 |
+
|
| 52 |
+
def discard(self, key):
|
| 53 |
+
"""If the keyed message exists, remove it."""
|
| 54 |
+
try:
|
| 55 |
+
self.remove(key)
|
| 56 |
+
except KeyError:
|
| 57 |
+
pass
|
| 58 |
+
|
| 59 |
+
def __setitem__(self, key, message):
|
| 60 |
+
"""Replace the keyed message; raise KeyError if it doesn't exist."""
|
| 61 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 62 |
+
|
| 63 |
+
def get(self, key, default=None):
|
| 64 |
+
"""Return the keyed message, or default if it doesn't exist."""
|
| 65 |
+
try:
|
| 66 |
+
return self.__getitem__(key)
|
| 67 |
+
except KeyError:
|
| 68 |
+
return default
|
| 69 |
+
|
| 70 |
+
def __getitem__(self, key):
|
| 71 |
+
"""Return the keyed message; raise KeyError if it doesn't exist."""
|
| 72 |
+
if not self._factory:
|
| 73 |
+
return self.get_message(key)
|
| 74 |
+
else:
|
| 75 |
+
with contextlib.closing(self.get_file(key)) as file:
|
| 76 |
+
return self._factory(file)
|
| 77 |
+
|
| 78 |
+
def get_message(self, key):
|
| 79 |
+
"""Return a Message representation or raise a KeyError."""
|
| 80 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 81 |
+
|
| 82 |
+
def get_string(self, key):
|
| 83 |
+
"""Return a string representation or raise a KeyError.
|
| 84 |
+
|
| 85 |
+
Uses email.message.Message to create a 7bit clean string
|
| 86 |
+
representation of the message."""
|
| 87 |
+
return email.message_from_bytes(self.get_bytes(key)).as_string()
|
| 88 |
+
|
| 89 |
+
def get_bytes(self, key):
|
| 90 |
+
"""Return a byte string representation or raise a KeyError."""
|
| 91 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 92 |
+
|
| 93 |
+
def get_file(self, key):
|
| 94 |
+
"""Return a file-like representation or raise a KeyError."""
|
| 95 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 96 |
+
|
| 97 |
+
def iterkeys(self):
|
| 98 |
+
"""Return an iterator over keys."""
|
| 99 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 100 |
+
|
| 101 |
+
def keys(self):
|
| 102 |
+
"""Return a list of keys."""
|
| 103 |
+
return list(self.iterkeys())
|
| 104 |
+
|
| 105 |
+
def itervalues(self):
|
| 106 |
+
"""Return an iterator over all messages."""
|
| 107 |
+
for key in self.iterkeys():
|
| 108 |
+
try:
|
| 109 |
+
value = self[key]
|
| 110 |
+
except KeyError:
|
| 111 |
+
continue
|
| 112 |
+
yield value
|
| 113 |
+
|
| 114 |
+
def __iter__(self):
|
| 115 |
+
return self.itervalues()
|
| 116 |
+
|
| 117 |
+
def values(self):
|
| 118 |
+
"""Return a list of messages. Memory intensive."""
|
| 119 |
+
return list(self.itervalues())
|
| 120 |
+
|
| 121 |
+
def iteritems(self):
|
| 122 |
+
"""Return an iterator over (key, message) tuples."""
|
| 123 |
+
for key in self.iterkeys():
|
| 124 |
+
try:
|
| 125 |
+
value = self[key]
|
| 126 |
+
except KeyError:
|
| 127 |
+
continue
|
| 128 |
+
yield (key, value)
|
| 129 |
+
|
| 130 |
+
def items(self):
|
| 131 |
+
"""Return a list of (key, message) tuples. Memory intensive."""
|
| 132 |
+
return list(self.iteritems())
|
| 133 |
+
|
| 134 |
+
def __contains__(self, key):
|
| 135 |
+
"""Return True if the keyed message exists, False otherwise."""
|
| 136 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 137 |
+
|
| 138 |
+
def __len__(self):
|
| 139 |
+
"""Return a count of messages in the mailbox."""
|
| 140 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 141 |
+
|
| 142 |
+
def clear(self):
|
| 143 |
+
"""Delete all messages."""
|
| 144 |
+
for key in self.keys():
|
| 145 |
+
self.discard(key)
|
| 146 |
+
|
| 147 |
+
def pop(self, key, default=None):
|
| 148 |
+
"""Delete the keyed message and return it, or default."""
|
| 149 |
+
try:
|
| 150 |
+
result = self[key]
|
| 151 |
+
except KeyError:
|
| 152 |
+
return default
|
| 153 |
+
self.discard(key)
|
| 154 |
+
return result
|
| 155 |
+
|
| 156 |
+
def popitem(self):
|
| 157 |
+
"""Delete an arbitrary (key, message) pair and return it."""
|
| 158 |
+
for key in self.iterkeys():
|
| 159 |
+
return (key, self.pop(key)) # This is only run once.
|
| 160 |
+
else:
|
| 161 |
+
raise KeyError('No messages in mailbox')
|
| 162 |
+
|
| 163 |
+
def update(self, arg=None):
|
| 164 |
+
"""Change the messages that correspond to certain keys."""
|
| 165 |
+
if hasattr(arg, 'iteritems'):
|
| 166 |
+
source = arg.iteritems()
|
| 167 |
+
elif hasattr(arg, 'items'):
|
| 168 |
+
source = arg.items()
|
| 169 |
+
else:
|
| 170 |
+
source = arg
|
| 171 |
+
bad_key = False
|
| 172 |
+
for key, message in source:
|
| 173 |
+
try:
|
| 174 |
+
self[key] = message
|
| 175 |
+
except KeyError:
|
| 176 |
+
bad_key = True
|
| 177 |
+
if bad_key:
|
| 178 |
+
raise KeyError('No message with key(s)')
|
| 179 |
+
|
| 180 |
+
def flush(self):
|
| 181 |
+
"""Write any pending changes to the disk."""
|
| 182 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 183 |
+
|
| 184 |
+
def lock(self):
|
| 185 |
+
"""Lock the mailbox."""
|
| 186 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 187 |
+
|
| 188 |
+
def unlock(self):
|
| 189 |
+
"""Unlock the mailbox if it is locked."""
|
| 190 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 191 |
+
|
| 192 |
+
def close(self):
|
| 193 |
+
"""Flush and close the mailbox."""
|
| 194 |
+
raise NotImplementedError('Method must be implemented by subclass')
|
| 195 |
+
|
| 196 |
+
def _string_to_bytes(self, message):
|
| 197 |
+
# If a message is not 7bit clean, we refuse to handle it since it
|
| 198 |
+
# likely came from reading invalid messages in text mode, and that way
|
| 199 |
+
# lies mojibake.
|
| 200 |
+
try:
|
| 201 |
+
return message.encode('ascii')
|
| 202 |
+
except UnicodeError:
|
| 203 |
+
raise ValueError("String input must be ASCII-only; "
|
| 204 |
+
"use bytes or a Message instead")
|
| 205 |
+
|
| 206 |
+
# Whether each message must end in a newline
|
| 207 |
+
_append_newline = False
|
| 208 |
+
|
| 209 |
+
def _dump_message(self, message, target, mangle_from_=False):
|
| 210 |
+
# This assumes the target file is open in binary mode.
|
| 211 |
+
"""Dump message contents to target file."""
|
| 212 |
+
if isinstance(message, email.message.Message):
|
| 213 |
+
buffer = io.BytesIO()
|
| 214 |
+
gen = email.generator.BytesGenerator(buffer, mangle_from_, 0)
|
| 215 |
+
gen.flatten(message)
|
| 216 |
+
buffer.seek(0)
|
| 217 |
+
data = buffer.read()
|
| 218 |
+
data = data.replace(b'\n', linesep)
|
| 219 |
+
target.write(data)
|
| 220 |
+
if self._append_newline and not data.endswith(linesep):
|
| 221 |
+
# Make sure the message ends with a newline
|
| 222 |
+
target.write(linesep)
|
| 223 |
+
elif isinstance(message, (str, bytes, io.StringIO)):
|
| 224 |
+
if isinstance(message, io.StringIO):
|
| 225 |
+
warnings.warn("Use of StringIO input is deprecated, "
|
| 226 |
+
"use BytesIO instead", DeprecationWarning, 3)
|
| 227 |
+
message = message.getvalue()
|
| 228 |
+
if isinstance(message, str):
|
| 229 |
+
message = self._string_to_bytes(message)
|
| 230 |
+
if mangle_from_:
|
| 231 |
+
message = message.replace(b'\nFrom ', b'\n>From ')
|
| 232 |
+
message = message.replace(b'\n', linesep)
|
| 233 |
+
target.write(message)
|
| 234 |
+
if self._append_newline and not message.endswith(linesep):
|
| 235 |
+
# Make sure the message ends with a newline
|
| 236 |
+
target.write(linesep)
|
| 237 |
+
elif hasattr(message, 'read'):
|
| 238 |
+
if hasattr(message, 'buffer'):
|
| 239 |
+
warnings.warn("Use of text mode files is deprecated, "
|
| 240 |
+
"use a binary mode file instead", DeprecationWarning, 3)
|
| 241 |
+
message = message.buffer
|
| 242 |
+
lastline = None
|
| 243 |
+
while True:
|
| 244 |
+
line = message.readline()
|
| 245 |
+
# Universal newline support.
|
| 246 |
+
if line.endswith(b'\r\n'):
|
| 247 |
+
line = line[:-2] + b'\n'
|
| 248 |
+
elif line.endswith(b'\r'):
|
| 249 |
+
line = line[:-1] + b'\n'
|
| 250 |
+
if not line:
|
| 251 |
+
break
|
| 252 |
+
if mangle_from_ and line.startswith(b'From '):
|
| 253 |
+
line = b'>From ' + line[5:]
|
| 254 |
+
line = line.replace(b'\n', linesep)
|
| 255 |
+
target.write(line)
|
| 256 |
+
lastline = line
|
| 257 |
+
if self._append_newline and lastline and not lastline.endswith(linesep):
|
| 258 |
+
# Make sure the message ends with a newline
|
| 259 |
+
target.write(linesep)
|
| 260 |
+
else:
|
| 261 |
+
raise TypeError('Invalid message type: %s' % type(message))
|
| 262 |
+
|
| 263 |
+
|
| 264 |
+
class Maildir(Mailbox):
|
| 265 |
+
"""A qmail-style Maildir mailbox."""
|
| 266 |
+
|
| 267 |
+
colon = ':'
|
| 268 |
+
|
| 269 |
+
def __init__(self, dirname, factory=None, create=True):
|
| 270 |
+
"""Initialize a Maildir instance."""
|
| 271 |
+
Mailbox.__init__(self, dirname, factory, create)
|
| 272 |
+
self._paths = {
|
| 273 |
+
'tmp': os.path.join(self._path, 'tmp'),
|
| 274 |
+
'new': os.path.join(self._path, 'new'),
|
| 275 |
+
'cur': os.path.join(self._path, 'cur'),
|
| 276 |
+
}
|
| 277 |
+
if not os.path.exists(self._path):
|
| 278 |
+
if create:
|
| 279 |
+
os.mkdir(self._path, 0o700)
|
| 280 |
+
for path in self._paths.values():
|
| 281 |
+
os.mkdir(path, 0o700)
|
| 282 |
+
else:
|
| 283 |
+
raise NoSuchMailboxError(self._path)
|
| 284 |
+
self._toc = {}
|
| 285 |
+
self._toc_mtimes = {'cur': 0, 'new': 0}
|
| 286 |
+
self._last_read = 0 # Records last time we read cur/new
|
| 287 |
+
self._skewfactor = 0.1 # Adjust if os/fs clocks are skewing
|
| 288 |
+
|
| 289 |
+
def add(self, message):
|
| 290 |
+
"""Add message and return assigned key."""
|
| 291 |
+
tmp_file = self._create_tmp()
|
| 292 |
+
try:
|
| 293 |
+
self._dump_message(message, tmp_file)
|
| 294 |
+
except BaseException:
|
| 295 |
+
tmp_file.close()
|
| 296 |
+
os.remove(tmp_file.name)
|
| 297 |
+
raise
|
| 298 |
+
_sync_close(tmp_file)
|
| 299 |
+
if isinstance(message, MaildirMessage):
|
| 300 |
+
subdir = message.get_subdir()
|
| 301 |
+
suffix = self.colon + message.get_info()
|
| 302 |
+
if suffix == self.colon:
|
| 303 |
+
suffix = ''
|
| 304 |
+
else:
|
| 305 |
+
subdir = 'new'
|
| 306 |
+
suffix = ''
|
| 307 |
+
uniq = os.path.basename(tmp_file.name).split(self.colon)[0]
|
| 308 |
+
dest = os.path.join(self._path, subdir, uniq + suffix)
|
| 309 |
+
if isinstance(message, MaildirMessage):
|
| 310 |
+
os.utime(tmp_file.name,
|
| 311 |
+
(os.path.getatime(tmp_file.name), message.get_date()))
|
| 312 |
+
# No file modification should be done after the file is moved to its
|
| 313 |
+
# final position in order to prevent race conditions with changes
|
| 314 |
+
# from other programs
|
| 315 |
+
try:
|
| 316 |
+
try:
|
| 317 |
+
os.link(tmp_file.name, dest)
|
| 318 |
+
except (AttributeError, PermissionError):
|
| 319 |
+
os.rename(tmp_file.name, dest)
|
| 320 |
+
else:
|
| 321 |
+
os.remove(tmp_file.name)
|
| 322 |
+
except OSError as e:
|
| 323 |
+
os.remove(tmp_file.name)
|
| 324 |
+
if e.errno == errno.EEXIST:
|
| 325 |
+
raise ExternalClashError('Name clash with existing message: %s'
|
| 326 |
+
% dest)
|
| 327 |
+
else:
|
| 328 |
+
raise
|
| 329 |
+
return uniq
|
| 330 |
+
|
| 331 |
+
def remove(self, key):
|
| 332 |
+
"""Remove the keyed message; raise KeyError if it doesn't exist."""
|
| 333 |
+
os.remove(os.path.join(self._path, self._lookup(key)))
|
| 334 |
+
|
| 335 |
+
def discard(self, key):
|
| 336 |
+
"""If the keyed message exists, remove it."""
|
| 337 |
+
# This overrides an inapplicable implementation in the superclass.
|
| 338 |
+
try:
|
| 339 |
+
self.remove(key)
|
| 340 |
+
except (KeyError, FileNotFoundError):
|
| 341 |
+
pass
|
| 342 |
+
|
| 343 |
+
def __setitem__(self, key, message):
|
| 344 |
+
"""Replace the keyed message; raise KeyError if it doesn't exist."""
|
| 345 |
+
old_subpath = self._lookup(key)
|
| 346 |
+
temp_key = self.add(message)
|
| 347 |
+
temp_subpath = self._lookup(temp_key)
|
| 348 |
+
if isinstance(message, MaildirMessage):
|
| 349 |
+
# temp's subdir and suffix were specified by message.
|
| 350 |
+
dominant_subpath = temp_subpath
|
| 351 |
+
else:
|
| 352 |
+
# temp's subdir and suffix were defaults from add().
|
| 353 |
+
dominant_subpath = old_subpath
|
| 354 |
+
subdir = os.path.dirname(dominant_subpath)
|
| 355 |
+
if self.colon in dominant_subpath:
|
| 356 |
+
suffix = self.colon + dominant_subpath.split(self.colon)[-1]
|
| 357 |
+
else:
|
| 358 |
+
suffix = ''
|
| 359 |
+
self.discard(key)
|
| 360 |
+
tmp_path = os.path.join(self._path, temp_subpath)
|
| 361 |
+
new_path = os.path.join(self._path, subdir, key + suffix)
|
| 362 |
+
if isinstance(message, MaildirMessage):
|
| 363 |
+
os.utime(tmp_path,
|
| 364 |
+
(os.path.getatime(tmp_path), message.get_date()))
|
| 365 |
+
# No file modification should be done after the file is moved to its
|
| 366 |
+
# final position in order to prevent race conditions with changes
|
| 367 |
+
# from other programs
|
| 368 |
+
os.rename(tmp_path, new_path)
|
| 369 |
+
|
| 370 |
+
def get_message(self, key):
|
| 371 |
+
"""Return a Message representation or raise a KeyError."""
|
| 372 |
+
subpath = self._lookup(key)
|
| 373 |
+
with open(os.path.join(self._path, subpath), 'rb') as f:
|
| 374 |
+
if self._factory:
|
| 375 |
+
msg = self._factory(f)
|
| 376 |
+
else:
|
| 377 |
+
msg = MaildirMessage(f)
|
| 378 |
+
subdir, name = os.path.split(subpath)
|
| 379 |
+
msg.set_subdir(subdir)
|
| 380 |
+
if self.colon in name:
|
| 381 |
+
msg.set_info(name.split(self.colon)[-1])
|
| 382 |
+
msg.set_date(os.path.getmtime(os.path.join(self._path, subpath)))
|
| 383 |
+
return msg
|
| 384 |
+
|
| 385 |
+
def get_bytes(self, key):
|
| 386 |
+
"""Return a bytes representation or raise a KeyError."""
|
| 387 |
+
with open(os.path.join(self._path, self._lookup(key)), 'rb') as f:
|
| 388 |
+
return f.read().replace(linesep, b'\n')
|
| 389 |
+
|
| 390 |
+
def get_file(self, key):
|
| 391 |
+
"""Return a file-like representation or raise a KeyError."""
|
| 392 |
+
f = open(os.path.join(self._path, self._lookup(key)), 'rb')
|
| 393 |
+
return _ProxyFile(f)
|
| 394 |
+
|
| 395 |
+
def iterkeys(self):
|
| 396 |
+
"""Return an iterator over keys."""
|
| 397 |
+
self._refresh()
|
| 398 |
+
for key in self._toc:
|
| 399 |
+
try:
|
| 400 |
+
self._lookup(key)
|
| 401 |
+
except KeyError:
|
| 402 |
+
continue
|
| 403 |
+
yield key
|
| 404 |
+
|
| 405 |
+
def __contains__(self, key):
|
| 406 |
+
"""Return True if the keyed message exists, False otherwise."""
|
| 407 |
+
self._refresh()
|
| 408 |
+
return key in self._toc
|
| 409 |
+
|
| 410 |
+
def __len__(self):
|
| 411 |
+
"""Return a count of messages in the mailbox."""
|
| 412 |
+
self._refresh()
|
| 413 |
+
return len(self._toc)
|
| 414 |
+
|
| 415 |
+
def flush(self):
|
| 416 |
+
"""Write any pending changes to disk."""
|
| 417 |
+
# Maildir changes are always written immediately, so there's nothing
|
| 418 |
+
# to do.
|
| 419 |
+
pass
|
| 420 |
+
|
| 421 |
+
def lock(self):
|
| 422 |
+
"""Lock the mailbox."""
|
| 423 |
+
return
|
| 424 |
+
|
| 425 |
+
def unlock(self):
|
| 426 |
+
"""Unlock the mailbox if it is locked."""
|
| 427 |
+
return
|
| 428 |
+
|
| 429 |
+
def close(self):
|
| 430 |
+
"""Flush and close the mailbox."""
|
| 431 |
+
return
|
| 432 |
+
|
| 433 |
+
def list_folders(self):
|
| 434 |
+
"""Return a list of folder names."""
|
| 435 |
+
result = []
|
| 436 |
+
for entry in os.listdir(self._path):
|
| 437 |
+
if len(entry) > 1 and entry[0] == '.' and \
|
| 438 |
+
os.path.isdir(os.path.join(self._path, entry)):
|
| 439 |
+
result.append(entry[1:])
|
| 440 |
+
return result
|
| 441 |
+
|
| 442 |
+
def get_folder(self, folder):
|
| 443 |
+
"""Return a Maildir instance for the named folder."""
|
| 444 |
+
return Maildir(os.path.join(self._path, '.' + folder),
|
| 445 |
+
factory=self._factory,
|
| 446 |
+
create=False)
|
| 447 |
+
|
| 448 |
+
def add_folder(self, folder):
|
| 449 |
+
"""Create a folder and return a Maildir instance representing it."""
|
| 450 |
+
path = os.path.join(self._path, '.' + folder)
|
| 451 |
+
result = Maildir(path, factory=self._factory)
|
| 452 |
+
maildirfolder_path = os.path.join(path, 'maildirfolder')
|
| 453 |
+
if not os.path.exists(maildirfolder_path):
|
| 454 |
+
os.close(os.open(maildirfolder_path, os.O_CREAT | os.O_WRONLY,
|
| 455 |
+
0o666))
|
| 456 |
+
return result
|
| 457 |
+
|
| 458 |
+
def remove_folder(self, folder):
|
| 459 |
+
"""Delete the named folder, which must be empty."""
|
| 460 |
+
path = os.path.join(self._path, '.' + folder)
|
| 461 |
+
for entry in os.listdir(os.path.join(path, 'new')) + \
|
| 462 |
+
os.listdir(os.path.join(path, 'cur')):
|
| 463 |
+
if len(entry) < 1 or entry[0] != '.':
|
| 464 |
+
raise NotEmptyError('Folder contains message(s): %s' % folder)
|
| 465 |
+
for entry in os.listdir(path):
|
| 466 |
+
if entry != 'new' and entry != 'cur' and entry != 'tmp' and \
|
| 467 |
+
os.path.isdir(os.path.join(path, entry)):
|
| 468 |
+
raise NotEmptyError("Folder contains subdirectory '%s': %s" %
|
| 469 |
+
(folder, entry))
|
| 470 |
+
for root, dirs, files in os.walk(path, topdown=False):
|
| 471 |
+
for entry in files:
|
| 472 |
+
os.remove(os.path.join(root, entry))
|
| 473 |
+
for entry in dirs:
|
| 474 |
+
os.rmdir(os.path.join(root, entry))
|
| 475 |
+
os.rmdir(path)
|
| 476 |
+
|
| 477 |
+
def clean(self):
|
| 478 |
+
"""Delete old files in "tmp"."""
|
| 479 |
+
now = time.time()
|
| 480 |
+
for entry in os.listdir(os.path.join(self._path, 'tmp')):
|
| 481 |
+
path = os.path.join(self._path, 'tmp', entry)
|
| 482 |
+
if now - os.path.getatime(path) > 129600: # 60 * 60 * 36
|
| 483 |
+
os.remove(path)
|
| 484 |
+
|
| 485 |
+
_count = 1 # This is used to generate unique file names.
|
| 486 |
+
|
| 487 |
+
def _create_tmp(self):
|
| 488 |
+
"""Create a file in the tmp subdirectory and open and return it."""
|
| 489 |
+
now = time.time()
|
| 490 |
+
hostname = socket.gethostname()
|
| 491 |
+
if '/' in hostname:
|
| 492 |
+
hostname = hostname.replace('/', r'\057')
|
| 493 |
+
if ':' in hostname:
|
| 494 |
+
hostname = hostname.replace(':', r'\072')
|
| 495 |
+
uniq = "%s.M%sP%sQ%s.%s" % (int(now), int(now % 1 * 1e6), os.getpid(),
|
| 496 |
+
Maildir._count, hostname)
|
| 497 |
+
path = os.path.join(self._path, 'tmp', uniq)
|
| 498 |
+
try:
|
| 499 |
+
os.stat(path)
|
| 500 |
+
except FileNotFoundError:
|
| 501 |
+
Maildir._count += 1
|
| 502 |
+
try:
|
| 503 |
+
return _create_carefully(path)
|
| 504 |
+
except FileExistsError:
|
| 505 |
+
pass
|
| 506 |
+
|
| 507 |
+
# Fall through to here if stat succeeded or open raised EEXIST.
|
| 508 |
+
raise ExternalClashError('Name clash prevented file creation: %s' %
|
| 509 |
+
path)
|
| 510 |
+
|
| 511 |
+
def _refresh(self):
|
| 512 |
+
"""Update table of contents mapping."""
|
| 513 |
+
# If it has been less than two seconds since the last _refresh() call,
|
| 514 |
+
# we have to unconditionally re-read the mailbox just in case it has
|
| 515 |
+
# been modified, because os.path.mtime() has a 2 sec resolution in the
|
| 516 |
+
# most common worst case (FAT) and a 1 sec resolution typically. This
|
| 517 |
+
# results in a few unnecessary re-reads when _refresh() is called
|
| 518 |
+
# multiple times in that interval, but once the clock ticks over, we
|
| 519 |
+
# will only re-read as needed. Because the filesystem might be being
|
| 520 |
+
# served by an independent system with its own clock, we record and
|
| 521 |
+
# compare with the mtimes from the filesystem. Because the other
|
| 522 |
+
# system's clock might be skewing relative to our clock, we add an
|
| 523 |
+
# extra delta to our wait. The default is one tenth second, but is an
|
| 524 |
+
# instance variable and so can be adjusted if dealing with a
|
| 525 |
+
# particularly skewed or irregular system.
|
| 526 |
+
if time.time() - self._last_read > 2 + self._skewfactor:
|
| 527 |
+
refresh = False
|
| 528 |
+
for subdir in self._toc_mtimes:
|
| 529 |
+
mtime = os.path.getmtime(self._paths[subdir])
|
| 530 |
+
if mtime > self._toc_mtimes[subdir]:
|
| 531 |
+
refresh = True
|
| 532 |
+
self._toc_mtimes[subdir] = mtime
|
| 533 |
+
if not refresh:
|
| 534 |
+
return
|
| 535 |
+
# Refresh toc
|
| 536 |
+
self._toc = {}
|
| 537 |
+
for subdir in self._toc_mtimes:
|
| 538 |
+
path = self._paths[subdir]
|
| 539 |
+
for entry in os.listdir(path):
|
| 540 |
+
p = os.path.join(path, entry)
|
| 541 |
+
if os.path.isdir(p):
|
| 542 |
+
continue
|
| 543 |
+
uniq = entry.split(self.colon)[0]
|
| 544 |
+
self._toc[uniq] = os.path.join(subdir, entry)
|
| 545 |
+
self._last_read = time.time()
|
| 546 |
+
|
| 547 |
+
def _lookup(self, key):
|
| 548 |
+
"""Use TOC to return subpath for given key, or raise a KeyError."""
|
| 549 |
+
try:
|
| 550 |
+
if os.path.exists(os.path.join(self._path, self._toc[key])):
|
| 551 |
+
return self._toc[key]
|
| 552 |
+
except KeyError:
|
| 553 |
+
pass
|
| 554 |
+
self._refresh()
|
| 555 |
+
try:
|
| 556 |
+
return self._toc[key]
|
| 557 |
+
except KeyError:
|
| 558 |
+
raise KeyError('No message with key: %s' % key) from None
|
| 559 |
+
|
| 560 |
+
# This method is for backward compatibility only.
|
| 561 |
+
def next(self):
|
| 562 |
+
"""Return the next message in a one-time iteration."""
|
| 563 |
+
if not hasattr(self, '_onetime_keys'):
|
| 564 |
+
self._onetime_keys = self.iterkeys()
|
| 565 |
+
while True:
|
| 566 |
+
try:
|
| 567 |
+
return self[next(self._onetime_keys)]
|
| 568 |
+
except StopIteration:
|
| 569 |
+
return None
|
| 570 |
+
except KeyError:
|
| 571 |
+
continue
|
| 572 |
+
|
| 573 |
+
|
| 574 |
+
class _singlefileMailbox(Mailbox):
|
| 575 |
+
"""A single-file mailbox."""
|
| 576 |
+
|
| 577 |
+
def __init__(self, path, factory=None, create=True):
|
| 578 |
+
"""Initialize a single-file mailbox."""
|
| 579 |
+
Mailbox.__init__(self, path, factory, create)
|
| 580 |
+
try:
|
| 581 |
+
f = open(self._path, 'rb+')
|
| 582 |
+
except OSError as e:
|
| 583 |
+
if e.errno == errno.ENOENT:
|
| 584 |
+
if create:
|
| 585 |
+
f = open(self._path, 'wb+')
|
| 586 |
+
else:
|
| 587 |
+
raise NoSuchMailboxError(self._path)
|
| 588 |
+
elif e.errno in (errno.EACCES, errno.EROFS):
|
| 589 |
+
f = open(self._path, 'rb')
|
| 590 |
+
else:
|
| 591 |
+
raise
|
| 592 |
+
self._file = f
|
| 593 |
+
self._toc = None
|
| 594 |
+
self._next_key = 0
|
| 595 |
+
self._pending = False # No changes require rewriting the file.
|
| 596 |
+
self._pending_sync = False # No need to sync the file
|
| 597 |
+
self._locked = False
|
| 598 |
+
self._file_length = None # Used to record mailbox size
|
| 599 |
+
|
| 600 |
+
def add(self, message):
|
| 601 |
+
"""Add message and return assigned key."""
|
| 602 |
+
self._lookup()
|
| 603 |
+
self._toc[self._next_key] = self._append_message(message)
|
| 604 |
+
self._next_key += 1
|
| 605 |
+
# _append_message appends the message to the mailbox file. We
|
| 606 |
+
# don't need a full rewrite + rename, sync is enough.
|
| 607 |
+
self._pending_sync = True
|
| 608 |
+
return self._next_key - 1
|
| 609 |
+
|
| 610 |
+
def remove(self, key):
|
| 611 |
+
"""Remove the keyed message; raise KeyError if it doesn't exist."""
|
| 612 |
+
self._lookup(key)
|
| 613 |
+
del self._toc[key]
|
| 614 |
+
self._pending = True
|
| 615 |
+
|
| 616 |
+
def __setitem__(self, key, message):
|
| 617 |
+
"""Replace the keyed message; raise KeyError if it doesn't exist."""
|
| 618 |
+
self._lookup(key)
|
| 619 |
+
self._toc[key] = self._append_message(message)
|
| 620 |
+
self._pending = True
|
| 621 |
+
|
| 622 |
+
def iterkeys(self):
|
| 623 |
+
"""Return an iterator over keys."""
|
| 624 |
+
self._lookup()
|
| 625 |
+
yield from self._toc.keys()
|
| 626 |
+
|
| 627 |
+
def __contains__(self, key):
|
| 628 |
+
"""Return True if the keyed message exists, False otherwise."""
|
| 629 |
+
self._lookup()
|
| 630 |
+
return key in self._toc
|
| 631 |
+
|
| 632 |
+
def __len__(self):
|
| 633 |
+
"""Return a count of messages in the mailbox."""
|
| 634 |
+
self._lookup()
|
| 635 |
+
return len(self._toc)
|
| 636 |
+
|
| 637 |
+
def lock(self):
|
| 638 |
+
"""Lock the mailbox."""
|
| 639 |
+
if not self._locked:
|
| 640 |
+
_lock_file(self._file)
|
| 641 |
+
self._locked = True
|
| 642 |
+
|
| 643 |
+
def unlock(self):
|
| 644 |
+
"""Unlock the mailbox if it is locked."""
|
| 645 |
+
if self._locked:
|
| 646 |
+
_unlock_file(self._file)
|
| 647 |
+
self._locked = False
|
| 648 |
+
|
| 649 |
+
def flush(self):
|
| 650 |
+
"""Write any pending changes to disk."""
|
| 651 |
+
if not self._pending:
|
| 652 |
+
if self._pending_sync:
|
| 653 |
+
# Messages have only been added, so syncing the file
|
| 654 |
+
# is enough.
|
| 655 |
+
_sync_flush(self._file)
|
| 656 |
+
self._pending_sync = False
|
| 657 |
+
return
|
| 658 |
+
|
| 659 |
+
# In order to be writing anything out at all, self._toc must
|
| 660 |
+
# already have been generated (and presumably has been modified
|
| 661 |
+
# by adding or deleting an item).
|
| 662 |
+
assert self._toc is not None
|
| 663 |
+
|
| 664 |
+
# Check length of self._file; if it's changed, some other process
|
| 665 |
+
# has modified the mailbox since we scanned it.
|
| 666 |
+
self._file.seek(0, 2)
|
| 667 |
+
cur_len = self._file.tell()
|
| 668 |
+
if cur_len != self._file_length:
|
| 669 |
+
raise ExternalClashError('Size of mailbox file changed '
|
| 670 |
+
'(expected %i, found %i)' %
|
| 671 |
+
(self._file_length, cur_len))
|
| 672 |
+
|
| 673 |
+
new_file = _create_temporary(self._path)
|
| 674 |
+
try:
|
| 675 |
+
new_toc = {}
|
| 676 |
+
self._pre_mailbox_hook(new_file)
|
| 677 |
+
for key in sorted(self._toc.keys()):
|
| 678 |
+
start, stop = self._toc[key]
|
| 679 |
+
self._file.seek(start)
|
| 680 |
+
self._pre_message_hook(new_file)
|
| 681 |
+
new_start = new_file.tell()
|
| 682 |
+
while True:
|
| 683 |
+
buffer = self._file.read(min(4096,
|
| 684 |
+
stop - self._file.tell()))
|
| 685 |
+
if not buffer:
|
| 686 |
+
break
|
| 687 |
+
new_file.write(buffer)
|
| 688 |
+
new_toc[key] = (new_start, new_file.tell())
|
| 689 |
+
self._post_message_hook(new_file)
|
| 690 |
+
self._file_length = new_file.tell()
|
| 691 |
+
except:
|
| 692 |
+
new_file.close()
|
| 693 |
+
os.remove(new_file.name)
|
| 694 |
+
raise
|
| 695 |
+
_sync_close(new_file)
|
| 696 |
+
# self._file is about to get replaced, so no need to sync.
|
| 697 |
+
self._file.close()
|
| 698 |
+
# Make sure the new file's mode is the same as the old file's
|
| 699 |
+
mode = os.stat(self._path).st_mode
|
| 700 |
+
os.chmod(new_file.name, mode)
|
| 701 |
+
try:
|
| 702 |
+
os.rename(new_file.name, self._path)
|
| 703 |
+
except FileExistsError:
|
| 704 |
+
os.remove(self._path)
|
| 705 |
+
os.rename(new_file.name, self._path)
|
| 706 |
+
self._file = open(self._path, 'rb+')
|
| 707 |
+
self._toc = new_toc
|
| 708 |
+
self._pending = False
|
| 709 |
+
self._pending_sync = False
|
| 710 |
+
if self._locked:
|
| 711 |
+
_lock_file(self._file, dotlock=False)
|
| 712 |
+
|
| 713 |
+
def _pre_mailbox_hook(self, f):
|
| 714 |
+
"""Called before writing the mailbox to file f."""
|
| 715 |
+
return
|
| 716 |
+
|
| 717 |
+
def _pre_message_hook(self, f):
|
| 718 |
+
"""Called before writing each message to file f."""
|
| 719 |
+
return
|
| 720 |
+
|
| 721 |
+
def _post_message_hook(self, f):
|
| 722 |
+
"""Called after writing each message to file f."""
|
| 723 |
+
return
|
| 724 |
+
|
| 725 |
+
def close(self):
|
| 726 |
+
"""Flush and close the mailbox."""
|
| 727 |
+
try:
|
| 728 |
+
self.flush()
|
| 729 |
+
finally:
|
| 730 |
+
try:
|
| 731 |
+
if self._locked:
|
| 732 |
+
self.unlock()
|
| 733 |
+
finally:
|
| 734 |
+
self._file.close() # Sync has been done by self.flush() above.
|
| 735 |
+
|
| 736 |
+
def _lookup(self, key=None):
|
| 737 |
+
"""Return (start, stop) or raise KeyError."""
|
| 738 |
+
if self._toc is None:
|
| 739 |
+
self._generate_toc()
|
| 740 |
+
if key is not None:
|
| 741 |
+
try:
|
| 742 |
+
return self._toc[key]
|
| 743 |
+
except KeyError:
|
| 744 |
+
raise KeyError('No message with key: %s' % key) from None
|
| 745 |
+
|
| 746 |
+
def _append_message(self, message):
|
| 747 |
+
"""Append message to mailbox and return (start, stop) offsets."""
|
| 748 |
+
self._file.seek(0, 2)
|
| 749 |
+
before = self._file.tell()
|
| 750 |
+
if len(self._toc) == 0 and not self._pending:
|
| 751 |
+
# This is the first message, and the _pre_mailbox_hook
|
| 752 |
+
# hasn't yet been called. If self._pending is True,
|
| 753 |
+
# messages have been removed, so _pre_mailbox_hook must
|
| 754 |
+
# have been called already.
|
| 755 |
+
self._pre_mailbox_hook(self._file)
|
| 756 |
+
try:
|
| 757 |
+
self._pre_message_hook(self._file)
|
| 758 |
+
offsets = self._install_message(message)
|
| 759 |
+
self._post_message_hook(self._file)
|
| 760 |
+
except BaseException:
|
| 761 |
+
self._file.truncate(before)
|
| 762 |
+
raise
|
| 763 |
+
self._file.flush()
|
| 764 |
+
self._file_length = self._file.tell() # Record current length of mailbox
|
| 765 |
+
return offsets
|
| 766 |
+
|
| 767 |
+
|
| 768 |
+
|
| 769 |
+
class _mboxMMDF(_singlefileMailbox):
|
| 770 |
+
"""An mbox or MMDF mailbox."""
|
| 771 |
+
|
| 772 |
+
_mangle_from_ = True
|
| 773 |
+
|
| 774 |
+
def get_message(self, key):
|
| 775 |
+
"""Return a Message representation or raise a KeyError."""
|
| 776 |
+
start, stop = self._lookup(key)
|
| 777 |
+
self._file.seek(start)
|
| 778 |
+
from_line = self._file.readline().replace(linesep, b'')
|
| 779 |
+
string = self._file.read(stop - self._file.tell())
|
| 780 |
+
msg = self._message_factory(string.replace(linesep, b'\n'))
|
| 781 |
+
msg.set_from(from_line[5:].decode('ascii'))
|
| 782 |
+
return msg
|
| 783 |
+
|
| 784 |
+
def get_string(self, key, from_=False):
|
| 785 |
+
"""Return a string representation or raise a KeyError."""
|
| 786 |
+
return email.message_from_bytes(
|
| 787 |
+
self.get_bytes(key, from_)).as_string(unixfrom=from_)
|
| 788 |
+
|
| 789 |
+
def get_bytes(self, key, from_=False):
|
| 790 |
+
"""Return a string representation or raise a KeyError."""
|
| 791 |
+
start, stop = self._lookup(key)
|
| 792 |
+
self._file.seek(start)
|
| 793 |
+
if not from_:
|
| 794 |
+
self._file.readline()
|
| 795 |
+
string = self._file.read(stop - self._file.tell())
|
| 796 |
+
return string.replace(linesep, b'\n')
|
| 797 |
+
|
| 798 |
+
def get_file(self, key, from_=False):
|
| 799 |
+
"""Return a file-like representation or raise a KeyError."""
|
| 800 |
+
start, stop = self._lookup(key)
|
| 801 |
+
self._file.seek(start)
|
| 802 |
+
if not from_:
|
| 803 |
+
self._file.readline()
|
| 804 |
+
return _PartialFile(self._file, self._file.tell(), stop)
|
| 805 |
+
|
| 806 |
+
def _install_message(self, message):
|
| 807 |
+
"""Format a message and blindly write to self._file."""
|
| 808 |
+
from_line = None
|
| 809 |
+
if isinstance(message, str):
|
| 810 |
+
message = self._string_to_bytes(message)
|
| 811 |
+
if isinstance(message, bytes) and message.startswith(b'From '):
|
| 812 |
+
newline = message.find(b'\n')
|
| 813 |
+
if newline != -1:
|
| 814 |
+
from_line = message[:newline]
|
| 815 |
+
message = message[newline + 1:]
|
| 816 |
+
else:
|
| 817 |
+
from_line = message
|
| 818 |
+
message = b''
|
| 819 |
+
elif isinstance(message, _mboxMMDFMessage):
|
| 820 |
+
author = message.get_from().encode('ascii')
|
| 821 |
+
from_line = b'From ' + author
|
| 822 |
+
elif isinstance(message, email.message.Message):
|
| 823 |
+
from_line = message.get_unixfrom() # May be None.
|
| 824 |
+
if from_line is not None:
|
| 825 |
+
from_line = from_line.encode('ascii')
|
| 826 |
+
if from_line is None:
|
| 827 |
+
from_line = b'From MAILER-DAEMON ' + time.asctime(time.gmtime()).encode()
|
| 828 |
+
start = self._file.tell()
|
| 829 |
+
self._file.write(from_line + linesep)
|
| 830 |
+
self._dump_message(message, self._file, self._mangle_from_)
|
| 831 |
+
stop = self._file.tell()
|
| 832 |
+
return (start, stop)
|
| 833 |
+
|
| 834 |
+
|
| 835 |
+
class mbox(_mboxMMDF):
|
| 836 |
+
"""A classic mbox mailbox."""
|
| 837 |
+
|
| 838 |
+
_mangle_from_ = True
|
| 839 |
+
|
| 840 |
+
# All messages must end in a newline character, and
|
| 841 |
+
# _post_message_hooks outputs an empty line between messages.
|
| 842 |
+
_append_newline = True
|
| 843 |
+
|
| 844 |
+
def __init__(self, path, factory=None, create=True):
|
| 845 |
+
"""Initialize an mbox mailbox."""
|
| 846 |
+
self._message_factory = mboxMessage
|
| 847 |
+
_mboxMMDF.__init__(self, path, factory, create)
|
| 848 |
+
|
| 849 |
+
def _post_message_hook(self, f):
|
| 850 |
+
"""Called after writing each message to file f."""
|
| 851 |
+
f.write(linesep)
|
| 852 |
+
|
| 853 |
+
def _generate_toc(self):
|
| 854 |
+
"""Generate key-to-(start, stop) table of contents."""
|
| 855 |
+
starts, stops = [], []
|
| 856 |
+
last_was_empty = False
|
| 857 |
+
self._file.seek(0)
|
| 858 |
+
while True:
|
| 859 |
+
line_pos = self._file.tell()
|
| 860 |
+
line = self._file.readline()
|
| 861 |
+
if line.startswith(b'From '):
|
| 862 |
+
if len(stops) < len(starts):
|
| 863 |
+
if last_was_empty:
|
| 864 |
+
stops.append(line_pos - len(linesep))
|
| 865 |
+
else:
|
| 866 |
+
# The last line before the "From " line wasn't
|
| 867 |
+
# blank, but we consider it a start of a
|
| 868 |
+
# message anyway.
|
| 869 |
+
stops.append(line_pos)
|
| 870 |
+
starts.append(line_pos)
|
| 871 |
+
last_was_empty = False
|
| 872 |
+
elif not line:
|
| 873 |
+
if last_was_empty:
|
| 874 |
+
stops.append(line_pos - len(linesep))
|
| 875 |
+
else:
|
| 876 |
+
stops.append(line_pos)
|
| 877 |
+
break
|
| 878 |
+
elif line == linesep:
|
| 879 |
+
last_was_empty = True
|
| 880 |
+
else:
|
| 881 |
+
last_was_empty = False
|
| 882 |
+
self._toc = dict(enumerate(zip(starts, stops)))
|
| 883 |
+
self._next_key = len(self._toc)
|
| 884 |
+
self._file_length = self._file.tell()
|
| 885 |
+
|
| 886 |
+
|
| 887 |
+
class MMDF(_mboxMMDF):
|
| 888 |
+
"""An MMDF mailbox."""
|
| 889 |
+
|
| 890 |
+
def __init__(self, path, factory=None, create=True):
|
| 891 |
+
"""Initialize an MMDF mailbox."""
|
| 892 |
+
self._message_factory = MMDFMessage
|
| 893 |
+
_mboxMMDF.__init__(self, path, factory, create)
|
| 894 |
+
|
| 895 |
+
def _pre_message_hook(self, f):
|
| 896 |
+
"""Called before writing each message to file f."""
|
| 897 |
+
f.write(b'\001\001\001\001' + linesep)
|
| 898 |
+
|
| 899 |
+
def _post_message_hook(self, f):
|
| 900 |
+
"""Called after writing each message to file f."""
|
| 901 |
+
f.write(linesep + b'\001\001\001\001' + linesep)
|
| 902 |
+
|
| 903 |
+
def _generate_toc(self):
|
| 904 |
+
"""Generate key-to-(start, stop) table of contents."""
|
| 905 |
+
starts, stops = [], []
|
| 906 |
+
self._file.seek(0)
|
| 907 |
+
next_pos = 0
|
| 908 |
+
while True:
|
| 909 |
+
line_pos = next_pos
|
| 910 |
+
line = self._file.readline()
|
| 911 |
+
next_pos = self._file.tell()
|
| 912 |
+
if line.startswith(b'\001\001\001\001' + linesep):
|
| 913 |
+
starts.append(next_pos)
|
| 914 |
+
while True:
|
| 915 |
+
line_pos = next_pos
|
| 916 |
+
line = self._file.readline()
|
| 917 |
+
next_pos = self._file.tell()
|
| 918 |
+
if line == b'\001\001\001\001' + linesep:
|
| 919 |
+
stops.append(line_pos - len(linesep))
|
| 920 |
+
break
|
| 921 |
+
elif not line:
|
| 922 |
+
stops.append(line_pos)
|
| 923 |
+
break
|
| 924 |
+
elif not line:
|
| 925 |
+
break
|
| 926 |
+
self._toc = dict(enumerate(zip(starts, stops)))
|
| 927 |
+
self._next_key = len(self._toc)
|
| 928 |
+
self._file.seek(0, 2)
|
| 929 |
+
self._file_length = self._file.tell()
|
| 930 |
+
|
| 931 |
+
|
| 932 |
+
class MH(Mailbox):
|
| 933 |
+
"""An MH mailbox."""
|
| 934 |
+
|
| 935 |
+
def __init__(self, path, factory=None, create=True):
|
| 936 |
+
"""Initialize an MH instance."""
|
| 937 |
+
Mailbox.__init__(self, path, factory, create)
|
| 938 |
+
if not os.path.exists(self._path):
|
| 939 |
+
if create:
|
| 940 |
+
os.mkdir(self._path, 0o700)
|
| 941 |
+
os.close(os.open(os.path.join(self._path, '.mh_sequences'),
|
| 942 |
+
os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600))
|
| 943 |
+
else:
|
| 944 |
+
raise NoSuchMailboxError(self._path)
|
| 945 |
+
self._locked = False
|
| 946 |
+
|
| 947 |
+
def add(self, message):
|
| 948 |
+
"""Add message and return assigned key."""
|
| 949 |
+
keys = self.keys()
|
| 950 |
+
if len(keys) == 0:
|
| 951 |
+
new_key = 1
|
| 952 |
+
else:
|
| 953 |
+
new_key = max(keys) + 1
|
| 954 |
+
new_path = os.path.join(self._path, str(new_key))
|
| 955 |
+
f = _create_carefully(new_path)
|
| 956 |
+
closed = False
|
| 957 |
+
try:
|
| 958 |
+
if self._locked:
|
| 959 |
+
_lock_file(f)
|
| 960 |
+
try:
|
| 961 |
+
try:
|
| 962 |
+
self._dump_message(message, f)
|
| 963 |
+
except BaseException:
|
| 964 |
+
# Unlock and close so it can be deleted on Windows
|
| 965 |
+
if self._locked:
|
| 966 |
+
_unlock_file(f)
|
| 967 |
+
_sync_close(f)
|
| 968 |
+
closed = True
|
| 969 |
+
os.remove(new_path)
|
| 970 |
+
raise
|
| 971 |
+
if isinstance(message, MHMessage):
|
| 972 |
+
self._dump_sequences(message, new_key)
|
| 973 |
+
finally:
|
| 974 |
+
if self._locked:
|
| 975 |
+
_unlock_file(f)
|
| 976 |
+
finally:
|
| 977 |
+
if not closed:
|
| 978 |
+
_sync_close(f)
|
| 979 |
+
return new_key
|
| 980 |
+
|
| 981 |
+
def remove(self, key):
|
| 982 |
+
"""Remove the keyed message; raise KeyError if it doesn't exist."""
|
| 983 |
+
path = os.path.join(self._path, str(key))
|
| 984 |
+
try:
|
| 985 |
+
f = open(path, 'rb+')
|
| 986 |
+
except OSError as e:
|
| 987 |
+
if e.errno == errno.ENOENT:
|
| 988 |
+
raise KeyError('No message with key: %s' % key)
|
| 989 |
+
else:
|
| 990 |
+
raise
|
| 991 |
+
else:
|
| 992 |
+
f.close()
|
| 993 |
+
os.remove(path)
|
| 994 |
+
|
| 995 |
+
def __setitem__(self, key, message):
|
| 996 |
+
"""Replace the keyed message; raise KeyError if it doesn't exist."""
|
| 997 |
+
path = os.path.join(self._path, str(key))
|
| 998 |
+
try:
|
| 999 |
+
f = open(path, 'rb+')
|
| 1000 |
+
except OSError as e:
|
| 1001 |
+
if e.errno == errno.ENOENT:
|
| 1002 |
+
raise KeyError('No message with key: %s' % key)
|
| 1003 |
+
else:
|
| 1004 |
+
raise
|
| 1005 |
+
try:
|
| 1006 |
+
if self._locked:
|
| 1007 |
+
_lock_file(f)
|
| 1008 |
+
try:
|
| 1009 |
+
os.close(os.open(path, os.O_WRONLY | os.O_TRUNC))
|
| 1010 |
+
self._dump_message(message, f)
|
| 1011 |
+
if isinstance(message, MHMessage):
|
| 1012 |
+
self._dump_sequences(message, key)
|
| 1013 |
+
finally:
|
| 1014 |
+
if self._locked:
|
| 1015 |
+
_unlock_file(f)
|
| 1016 |
+
finally:
|
| 1017 |
+
_sync_close(f)
|
| 1018 |
+
|
| 1019 |
+
def get_message(self, key):
|
| 1020 |
+
"""Return a Message representation or raise a KeyError."""
|
| 1021 |
+
try:
|
| 1022 |
+
if self._locked:
|
| 1023 |
+
f = open(os.path.join(self._path, str(key)), 'rb+')
|
| 1024 |
+
else:
|
| 1025 |
+
f = open(os.path.join(self._path, str(key)), 'rb')
|
| 1026 |
+
except OSError as e:
|
| 1027 |
+
if e.errno == errno.ENOENT:
|
| 1028 |
+
raise KeyError('No message with key: %s' % key)
|
| 1029 |
+
else:
|
| 1030 |
+
raise
|
| 1031 |
+
with f:
|
| 1032 |
+
if self._locked:
|
| 1033 |
+
_lock_file(f)
|
| 1034 |
+
try:
|
| 1035 |
+
msg = MHMessage(f)
|
| 1036 |
+
finally:
|
| 1037 |
+
if self._locked:
|
| 1038 |
+
_unlock_file(f)
|
| 1039 |
+
for name, key_list in self.get_sequences().items():
|
| 1040 |
+
if key in key_list:
|
| 1041 |
+
msg.add_sequence(name)
|
| 1042 |
+
return msg
|
| 1043 |
+
|
| 1044 |
+
def get_bytes(self, key):
|
| 1045 |
+
"""Return a bytes representation or raise a KeyError."""
|
| 1046 |
+
try:
|
| 1047 |
+
if self._locked:
|
| 1048 |
+
f = open(os.path.join(self._path, str(key)), 'rb+')
|
| 1049 |
+
else:
|
| 1050 |
+
f = open(os.path.join(self._path, str(key)), 'rb')
|
| 1051 |
+
except OSError as e:
|
| 1052 |
+
if e.errno == errno.ENOENT:
|
| 1053 |
+
raise KeyError('No message with key: %s' % key)
|
| 1054 |
+
else:
|
| 1055 |
+
raise
|
| 1056 |
+
with f:
|
| 1057 |
+
if self._locked:
|
| 1058 |
+
_lock_file(f)
|
| 1059 |
+
try:
|
| 1060 |
+
return f.read().replace(linesep, b'\n')
|
| 1061 |
+
finally:
|
| 1062 |
+
if self._locked:
|
| 1063 |
+
_unlock_file(f)
|
| 1064 |
+
|
| 1065 |
+
def get_file(self, key):
|
| 1066 |
+
"""Return a file-like representation or raise a KeyError."""
|
| 1067 |
+
try:
|
| 1068 |
+
f = open(os.path.join(self._path, str(key)), 'rb')
|
| 1069 |
+
except OSError as e:
|
| 1070 |
+
if e.errno == errno.ENOENT:
|
| 1071 |
+
raise KeyError('No message with key: %s' % key)
|
| 1072 |
+
else:
|
| 1073 |
+
raise
|
| 1074 |
+
return _ProxyFile(f)
|
| 1075 |
+
|
| 1076 |
+
def iterkeys(self):
|
| 1077 |
+
"""Return an iterator over keys."""
|
| 1078 |
+
return iter(sorted(int(entry) for entry in os.listdir(self._path)
|
| 1079 |
+
if entry.isdigit()))
|
| 1080 |
+
|
| 1081 |
+
def __contains__(self, key):
|
| 1082 |
+
"""Return True if the keyed message exists, False otherwise."""
|
| 1083 |
+
return os.path.exists(os.path.join(self._path, str(key)))
|
| 1084 |
+
|
| 1085 |
+
def __len__(self):
|
| 1086 |
+
"""Return a count of messages in the mailbox."""
|
| 1087 |
+
return len(list(self.iterkeys()))
|
| 1088 |
+
|
| 1089 |
+
def lock(self):
|
| 1090 |
+
"""Lock the mailbox."""
|
| 1091 |
+
if not self._locked:
|
| 1092 |
+
self._file = open(os.path.join(self._path, '.mh_sequences'), 'rb+')
|
| 1093 |
+
_lock_file(self._file)
|
| 1094 |
+
self._locked = True
|
| 1095 |
+
|
| 1096 |
+
def unlock(self):
|
| 1097 |
+
"""Unlock the mailbox if it is locked."""
|
| 1098 |
+
if self._locked:
|
| 1099 |
+
_unlock_file(self._file)
|
| 1100 |
+
_sync_close(self._file)
|
| 1101 |
+
del self._file
|
| 1102 |
+
self._locked = False
|
| 1103 |
+
|
| 1104 |
+
def flush(self):
|
| 1105 |
+
"""Write any pending changes to the disk."""
|
| 1106 |
+
return
|
| 1107 |
+
|
| 1108 |
+
def close(self):
|
| 1109 |
+
"""Flush and close the mailbox."""
|
| 1110 |
+
if self._locked:
|
| 1111 |
+
self.unlock()
|
| 1112 |
+
|
| 1113 |
+
def list_folders(self):
|
| 1114 |
+
"""Return a list of folder names."""
|
| 1115 |
+
result = []
|
| 1116 |
+
for entry in os.listdir(self._path):
|
| 1117 |
+
if os.path.isdir(os.path.join(self._path, entry)):
|
| 1118 |
+
result.append(entry)
|
| 1119 |
+
return result
|
| 1120 |
+
|
| 1121 |
+
def get_folder(self, folder):
|
| 1122 |
+
"""Return an MH instance for the named folder."""
|
| 1123 |
+
return MH(os.path.join(self._path, folder),
|
| 1124 |
+
factory=self._factory, create=False)
|
| 1125 |
+
|
| 1126 |
+
def add_folder(self, folder):
|
| 1127 |
+
"""Create a folder and return an MH instance representing it."""
|
| 1128 |
+
return MH(os.path.join(self._path, folder),
|
| 1129 |
+
factory=self._factory)
|
| 1130 |
+
|
| 1131 |
+
def remove_folder(self, folder):
|
| 1132 |
+
"""Delete the named folder, which must be empty."""
|
| 1133 |
+
path = os.path.join(self._path, folder)
|
| 1134 |
+
entries = os.listdir(path)
|
| 1135 |
+
if entries == ['.mh_sequences']:
|
| 1136 |
+
os.remove(os.path.join(path, '.mh_sequences'))
|
| 1137 |
+
elif entries == []:
|
| 1138 |
+
pass
|
| 1139 |
+
else:
|
| 1140 |
+
raise NotEmptyError('Folder not empty: %s' % self._path)
|
| 1141 |
+
os.rmdir(path)
|
| 1142 |
+
|
| 1143 |
+
def get_sequences(self):
|
| 1144 |
+
"""Return a name-to-key-list dictionary to define each sequence."""
|
| 1145 |
+
results = {}
|
| 1146 |
+
with open(os.path.join(self._path, '.mh_sequences'), 'r', encoding='ASCII') as f:
|
| 1147 |
+
all_keys = set(self.keys())
|
| 1148 |
+
for line in f:
|
| 1149 |
+
try:
|
| 1150 |
+
name, contents = line.split(':')
|
| 1151 |
+
keys = set()
|
| 1152 |
+
for spec in contents.split():
|
| 1153 |
+
if spec.isdigit():
|
| 1154 |
+
keys.add(int(spec))
|
| 1155 |
+
else:
|
| 1156 |
+
start, stop = (int(x) for x in spec.split('-'))
|
| 1157 |
+
keys.update(range(start, stop + 1))
|
| 1158 |
+
results[name] = [key for key in sorted(keys) \
|
| 1159 |
+
if key in all_keys]
|
| 1160 |
+
if len(results[name]) == 0:
|
| 1161 |
+
del results[name]
|
| 1162 |
+
except ValueError:
|
| 1163 |
+
raise FormatError('Invalid sequence specification: %s' %
|
| 1164 |
+
line.rstrip())
|
| 1165 |
+
return results
|
| 1166 |
+
|
| 1167 |
+
def set_sequences(self, sequences):
|
| 1168 |
+
"""Set sequences using the given name-to-key-list dictionary."""
|
| 1169 |
+
f = open(os.path.join(self._path, '.mh_sequences'), 'r+', encoding='ASCII')
|
| 1170 |
+
try:
|
| 1171 |
+
os.close(os.open(f.name, os.O_WRONLY | os.O_TRUNC))
|
| 1172 |
+
for name, keys in sequences.items():
|
| 1173 |
+
if len(keys) == 0:
|
| 1174 |
+
continue
|
| 1175 |
+
f.write(name + ':')
|
| 1176 |
+
prev = None
|
| 1177 |
+
completing = False
|
| 1178 |
+
for key in sorted(set(keys)):
|
| 1179 |
+
if key - 1 == prev:
|
| 1180 |
+
if not completing:
|
| 1181 |
+
completing = True
|
| 1182 |
+
f.write('-')
|
| 1183 |
+
elif completing:
|
| 1184 |
+
completing = False
|
| 1185 |
+
f.write('%s %s' % (prev, key))
|
| 1186 |
+
else:
|
| 1187 |
+
f.write(' %s' % key)
|
| 1188 |
+
prev = key
|
| 1189 |
+
if completing:
|
| 1190 |
+
f.write(str(prev) + '\n')
|
| 1191 |
+
else:
|
| 1192 |
+
f.write('\n')
|
| 1193 |
+
finally:
|
| 1194 |
+
_sync_close(f)
|
| 1195 |
+
|
| 1196 |
+
def pack(self):
|
| 1197 |
+
"""Re-name messages to eliminate numbering gaps. Invalidates keys."""
|
| 1198 |
+
sequences = self.get_sequences()
|
| 1199 |
+
prev = 0
|
| 1200 |
+
changes = []
|
| 1201 |
+
for key in self.iterkeys():
|
| 1202 |
+
if key - 1 != prev:
|
| 1203 |
+
changes.append((key, prev + 1))
|
| 1204 |
+
try:
|
| 1205 |
+
os.link(os.path.join(self._path, str(key)),
|
| 1206 |
+
os.path.join(self._path, str(prev + 1)))
|
| 1207 |
+
except (AttributeError, PermissionError):
|
| 1208 |
+
os.rename(os.path.join(self._path, str(key)),
|
| 1209 |
+
os.path.join(self._path, str(prev + 1)))
|
| 1210 |
+
else:
|
| 1211 |
+
os.unlink(os.path.join(self._path, str(key)))
|
| 1212 |
+
prev += 1
|
| 1213 |
+
self._next_key = prev + 1
|
| 1214 |
+
if len(changes) == 0:
|
| 1215 |
+
return
|
| 1216 |
+
for name, key_list in sequences.items():
|
| 1217 |
+
for old, new in changes:
|
| 1218 |
+
if old in key_list:
|
| 1219 |
+
key_list[key_list.index(old)] = new
|
| 1220 |
+
self.set_sequences(sequences)
|
| 1221 |
+
|
| 1222 |
+
def _dump_sequences(self, message, key):
|
| 1223 |
+
"""Inspect a new MHMessage and update sequences appropriately."""
|
| 1224 |
+
pending_sequences = message.get_sequences()
|
| 1225 |
+
all_sequences = self.get_sequences()
|
| 1226 |
+
for name, key_list in all_sequences.items():
|
| 1227 |
+
if name in pending_sequences:
|
| 1228 |
+
key_list.append(key)
|
| 1229 |
+
elif key in key_list:
|
| 1230 |
+
del key_list[key_list.index(key)]
|
| 1231 |
+
for sequence in pending_sequences:
|
| 1232 |
+
if sequence not in all_sequences:
|
| 1233 |
+
all_sequences[sequence] = [key]
|
| 1234 |
+
self.set_sequences(all_sequences)
|
| 1235 |
+
|
| 1236 |
+
|
| 1237 |
+
class Babyl(_singlefileMailbox):
|
| 1238 |
+
"""An Rmail-style Babyl mailbox."""
|
| 1239 |
+
|
| 1240 |
+
_special_labels = frozenset({'unseen', 'deleted', 'filed', 'answered',
|
| 1241 |
+
'forwarded', 'edited', 'resent'})
|
| 1242 |
+
|
| 1243 |
+
def __init__(self, path, factory=None, create=True):
|
| 1244 |
+
"""Initialize a Babyl mailbox."""
|
| 1245 |
+
_singlefileMailbox.__init__(self, path, factory, create)
|
| 1246 |
+
self._labels = {}
|
| 1247 |
+
|
| 1248 |
+
def add(self, message):
|
| 1249 |
+
"""Add message and return assigned key."""
|
| 1250 |
+
key = _singlefileMailbox.add(self, message)
|
| 1251 |
+
if isinstance(message, BabylMessage):
|
| 1252 |
+
self._labels[key] = message.get_labels()
|
| 1253 |
+
return key
|
| 1254 |
+
|
| 1255 |
+
def remove(self, key):
|
| 1256 |
+
"""Remove the keyed message; raise KeyError if it doesn't exist."""
|
| 1257 |
+
_singlefileMailbox.remove(self, key)
|
| 1258 |
+
if key in self._labels:
|
| 1259 |
+
del self._labels[key]
|
| 1260 |
+
|
| 1261 |
+
def __setitem__(self, key, message):
|
| 1262 |
+
"""Replace the keyed message; raise KeyError if it doesn't exist."""
|
| 1263 |
+
_singlefileMailbox.__setitem__(self, key, message)
|
| 1264 |
+
if isinstance(message, BabylMessage):
|
| 1265 |
+
self._labels[key] = message.get_labels()
|
| 1266 |
+
|
| 1267 |
+
def get_message(self, key):
|
| 1268 |
+
"""Return a Message representation or raise a KeyError."""
|
| 1269 |
+
start, stop = self._lookup(key)
|
| 1270 |
+
self._file.seek(start)
|
| 1271 |
+
self._file.readline() # Skip b'1,' line specifying labels.
|
| 1272 |
+
original_headers = io.BytesIO()
|
| 1273 |
+
while True:
|
| 1274 |
+
line = self._file.readline()
|
| 1275 |
+
if line == b'*** EOOH ***' + linesep or not line:
|
| 1276 |
+
break
|
| 1277 |
+
original_headers.write(line.replace(linesep, b'\n'))
|
| 1278 |
+
visible_headers = io.BytesIO()
|
| 1279 |
+
while True:
|
| 1280 |
+
line = self._file.readline()
|
| 1281 |
+
if line == linesep or not line:
|
| 1282 |
+
break
|
| 1283 |
+
visible_headers.write(line.replace(linesep, b'\n'))
|
| 1284 |
+
# Read up to the stop, or to the end
|
| 1285 |
+
n = stop - self._file.tell()
|
| 1286 |
+
assert n >= 0
|
| 1287 |
+
body = self._file.read(n)
|
| 1288 |
+
body = body.replace(linesep, b'\n')
|
| 1289 |
+
msg = BabylMessage(original_headers.getvalue() + body)
|
| 1290 |
+
msg.set_visible(visible_headers.getvalue())
|
| 1291 |
+
if key in self._labels:
|
| 1292 |
+
msg.set_labels(self._labels[key])
|
| 1293 |
+
return msg
|
| 1294 |
+
|
| 1295 |
+
def get_bytes(self, key):
|
| 1296 |
+
"""Return a string representation or raise a KeyError."""
|
| 1297 |
+
start, stop = self._lookup(key)
|
| 1298 |
+
self._file.seek(start)
|
| 1299 |
+
self._file.readline() # Skip b'1,' line specifying labels.
|
| 1300 |
+
original_headers = io.BytesIO()
|
| 1301 |
+
while True:
|
| 1302 |
+
line = self._file.readline()
|
| 1303 |
+
if line == b'*** EOOH ***' + linesep or not line:
|
| 1304 |
+
break
|
| 1305 |
+
original_headers.write(line.replace(linesep, b'\n'))
|
| 1306 |
+
while True:
|
| 1307 |
+
line = self._file.readline()
|
| 1308 |
+
if line == linesep or not line:
|
| 1309 |
+
break
|
| 1310 |
+
headers = original_headers.getvalue()
|
| 1311 |
+
n = stop - self._file.tell()
|
| 1312 |
+
assert n >= 0
|
| 1313 |
+
data = self._file.read(n)
|
| 1314 |
+
data = data.replace(linesep, b'\n')
|
| 1315 |
+
return headers + data
|
| 1316 |
+
|
| 1317 |
+
def get_file(self, key):
|
| 1318 |
+
"""Return a file-like representation or raise a KeyError."""
|
| 1319 |
+
return io.BytesIO(self.get_bytes(key).replace(b'\n', linesep))
|
| 1320 |
+
|
| 1321 |
+
def get_labels(self):
|
| 1322 |
+
"""Return a list of user-defined labels in the mailbox."""
|
| 1323 |
+
self._lookup()
|
| 1324 |
+
labels = set()
|
| 1325 |
+
for label_list in self._labels.values():
|
| 1326 |
+
labels.update(label_list)
|
| 1327 |
+
labels.difference_update(self._special_labels)
|
| 1328 |
+
return list(labels)
|
| 1329 |
+
|
| 1330 |
+
def _generate_toc(self):
|
| 1331 |
+
"""Generate key-to-(start, stop) table of contents."""
|
| 1332 |
+
starts, stops = [], []
|
| 1333 |
+
self._file.seek(0)
|
| 1334 |
+
next_pos = 0
|
| 1335 |
+
label_lists = []
|
| 1336 |
+
while True:
|
| 1337 |
+
line_pos = next_pos
|
| 1338 |
+
line = self._file.readline()
|
| 1339 |
+
next_pos = self._file.tell()
|
| 1340 |
+
if line == b'\037\014' + linesep:
|
| 1341 |
+
if len(stops) < len(starts):
|
| 1342 |
+
stops.append(line_pos - len(linesep))
|
| 1343 |
+
starts.append(next_pos)
|
| 1344 |
+
labels = [label.strip() for label
|
| 1345 |
+
in self._file.readline()[1:].split(b',')
|
| 1346 |
+
if label.strip()]
|
| 1347 |
+
label_lists.append(labels)
|
| 1348 |
+
elif line == b'\037' or line == b'\037' + linesep:
|
| 1349 |
+
if len(stops) < len(starts):
|
| 1350 |
+
stops.append(line_pos - len(linesep))
|
| 1351 |
+
elif not line:
|
| 1352 |
+
stops.append(line_pos - len(linesep))
|
| 1353 |
+
break
|
| 1354 |
+
self._toc = dict(enumerate(zip(starts, stops)))
|
| 1355 |
+
self._labels = dict(enumerate(label_lists))
|
| 1356 |
+
self._next_key = len(self._toc)
|
| 1357 |
+
self._file.seek(0, 2)
|
| 1358 |
+
self._file_length = self._file.tell()
|
| 1359 |
+
|
| 1360 |
+
def _pre_mailbox_hook(self, f):
|
| 1361 |
+
"""Called before writing the mailbox to file f."""
|
| 1362 |
+
babyl = b'BABYL OPTIONS:' + linesep
|
| 1363 |
+
babyl += b'Version: 5' + linesep
|
| 1364 |
+
labels = self.get_labels()
|
| 1365 |
+
labels = (label.encode() for label in labels)
|
| 1366 |
+
babyl += b'Labels:' + b','.join(labels) + linesep
|
| 1367 |
+
babyl += b'\037'
|
| 1368 |
+
f.write(babyl)
|
| 1369 |
+
|
| 1370 |
+
def _pre_message_hook(self, f):
|
| 1371 |
+
"""Called before writing each message to file f."""
|
| 1372 |
+
f.write(b'\014' + linesep)
|
| 1373 |
+
|
| 1374 |
+
def _post_message_hook(self, f):
|
| 1375 |
+
"""Called after writing each message to file f."""
|
| 1376 |
+
f.write(linesep + b'\037')
|
| 1377 |
+
|
| 1378 |
+
def _install_message(self, message):
|
| 1379 |
+
"""Write message contents and return (start, stop)."""
|
| 1380 |
+
start = self._file.tell()
|
| 1381 |
+
if isinstance(message, BabylMessage):
|
| 1382 |
+
special_labels = []
|
| 1383 |
+
labels = []
|
| 1384 |
+
for label in message.get_labels():
|
| 1385 |
+
if label in self._special_labels:
|
| 1386 |
+
special_labels.append(label)
|
| 1387 |
+
else:
|
| 1388 |
+
labels.append(label)
|
| 1389 |
+
self._file.write(b'1')
|
| 1390 |
+
for label in special_labels:
|
| 1391 |
+
self._file.write(b', ' + label.encode())
|
| 1392 |
+
self._file.write(b',,')
|
| 1393 |
+
for label in labels:
|
| 1394 |
+
self._file.write(b' ' + label.encode() + b',')
|
| 1395 |
+
self._file.write(linesep)
|
| 1396 |
+
else:
|
| 1397 |
+
self._file.write(b'1,,' + linesep)
|
| 1398 |
+
if isinstance(message, email.message.Message):
|
| 1399 |
+
orig_buffer = io.BytesIO()
|
| 1400 |
+
orig_generator = email.generator.BytesGenerator(orig_buffer, False, 0)
|
| 1401 |
+
orig_generator.flatten(message)
|
| 1402 |
+
orig_buffer.seek(0)
|
| 1403 |
+
while True:
|
| 1404 |
+
line = orig_buffer.readline()
|
| 1405 |
+
self._file.write(line.replace(b'\n', linesep))
|
| 1406 |
+
if line == b'\n' or not line:
|
| 1407 |
+
break
|
| 1408 |
+
self._file.write(b'*** EOOH ***' + linesep)
|
| 1409 |
+
if isinstance(message, BabylMessage):
|
| 1410 |
+
vis_buffer = io.BytesIO()
|
| 1411 |
+
vis_generator = email.generator.BytesGenerator(vis_buffer, False, 0)
|
| 1412 |
+
vis_generator.flatten(message.get_visible())
|
| 1413 |
+
while True:
|
| 1414 |
+
line = vis_buffer.readline()
|
| 1415 |
+
self._file.write(line.replace(b'\n', linesep))
|
| 1416 |
+
if line == b'\n' or not line:
|
| 1417 |
+
break
|
| 1418 |
+
else:
|
| 1419 |
+
orig_buffer.seek(0)
|
| 1420 |
+
while True:
|
| 1421 |
+
line = orig_buffer.readline()
|
| 1422 |
+
self._file.write(line.replace(b'\n', linesep))
|
| 1423 |
+
if line == b'\n' or not line:
|
| 1424 |
+
break
|
| 1425 |
+
while True:
|
| 1426 |
+
buffer = orig_buffer.read(4096) # Buffer size is arbitrary.
|
| 1427 |
+
if not buffer:
|
| 1428 |
+
break
|
| 1429 |
+
self._file.write(buffer.replace(b'\n', linesep))
|
| 1430 |
+
elif isinstance(message, (bytes, str, io.StringIO)):
|
| 1431 |
+
if isinstance(message, io.StringIO):
|
| 1432 |
+
warnings.warn("Use of StringIO input is deprecated, "
|
| 1433 |
+
"use BytesIO instead", DeprecationWarning, 3)
|
| 1434 |
+
message = message.getvalue()
|
| 1435 |
+
if isinstance(message, str):
|
| 1436 |
+
message = self._string_to_bytes(message)
|
| 1437 |
+
body_start = message.find(b'\n\n') + 2
|
| 1438 |
+
if body_start - 2 != -1:
|
| 1439 |
+
self._file.write(message[:body_start].replace(b'\n', linesep))
|
| 1440 |
+
self._file.write(b'*** EOOH ***' + linesep)
|
| 1441 |
+
self._file.write(message[:body_start].replace(b'\n', linesep))
|
| 1442 |
+
self._file.write(message[body_start:].replace(b'\n', linesep))
|
| 1443 |
+
else:
|
| 1444 |
+
self._file.write(b'*** EOOH ***' + linesep + linesep)
|
| 1445 |
+
self._file.write(message.replace(b'\n', linesep))
|
| 1446 |
+
elif hasattr(message, 'readline'):
|
| 1447 |
+
if hasattr(message, 'buffer'):
|
| 1448 |
+
warnings.warn("Use of text mode files is deprecated, "
|
| 1449 |
+
"use a binary mode file instead", DeprecationWarning, 3)
|
| 1450 |
+
message = message.buffer
|
| 1451 |
+
original_pos = message.tell()
|
| 1452 |
+
first_pass = True
|
| 1453 |
+
while True:
|
| 1454 |
+
line = message.readline()
|
| 1455 |
+
# Universal newline support.
|
| 1456 |
+
if line.endswith(b'\r\n'):
|
| 1457 |
+
line = line[:-2] + b'\n'
|
| 1458 |
+
elif line.endswith(b'\r'):
|
| 1459 |
+
line = line[:-1] + b'\n'
|
| 1460 |
+
self._file.write(line.replace(b'\n', linesep))
|
| 1461 |
+
if line == b'\n' or not line:
|
| 1462 |
+
if first_pass:
|
| 1463 |
+
first_pass = False
|
| 1464 |
+
self._file.write(b'*** EOOH ***' + linesep)
|
| 1465 |
+
message.seek(original_pos)
|
| 1466 |
+
else:
|
| 1467 |
+
break
|
| 1468 |
+
while True:
|
| 1469 |
+
line = message.readline()
|
| 1470 |
+
if not line:
|
| 1471 |
+
break
|
| 1472 |
+
# Universal newline support.
|
| 1473 |
+
if line.endswith(b'\r\n'):
|
| 1474 |
+
line = line[:-2] + linesep
|
| 1475 |
+
elif line.endswith(b'\r'):
|
| 1476 |
+
line = line[:-1] + linesep
|
| 1477 |
+
elif line.endswith(b'\n'):
|
| 1478 |
+
line = line[:-1] + linesep
|
| 1479 |
+
self._file.write(line)
|
| 1480 |
+
else:
|
| 1481 |
+
raise TypeError('Invalid message type: %s' % type(message))
|
| 1482 |
+
stop = self._file.tell()
|
| 1483 |
+
return (start, stop)
|
| 1484 |
+
|
| 1485 |
+
|
| 1486 |
+
class Message(email.message.Message):
|
| 1487 |
+
"""Message with mailbox-format-specific properties."""
|
| 1488 |
+
|
| 1489 |
+
def __init__(self, message=None):
|
| 1490 |
+
"""Initialize a Message instance."""
|
| 1491 |
+
if isinstance(message, email.message.Message):
|
| 1492 |
+
self._become_message(copy.deepcopy(message))
|
| 1493 |
+
if isinstance(message, Message):
|
| 1494 |
+
message._explain_to(self)
|
| 1495 |
+
elif isinstance(message, bytes):
|
| 1496 |
+
self._become_message(email.message_from_bytes(message))
|
| 1497 |
+
elif isinstance(message, str):
|
| 1498 |
+
self._become_message(email.message_from_string(message))
|
| 1499 |
+
elif isinstance(message, io.TextIOWrapper):
|
| 1500 |
+
self._become_message(email.message_from_file(message))
|
| 1501 |
+
elif hasattr(message, "read"):
|
| 1502 |
+
self._become_message(email.message_from_binary_file(message))
|
| 1503 |
+
elif message is None:
|
| 1504 |
+
email.message.Message.__init__(self)
|
| 1505 |
+
else:
|
| 1506 |
+
raise TypeError('Invalid message type: %s' % type(message))
|
| 1507 |
+
|
| 1508 |
+
def _become_message(self, message):
|
| 1509 |
+
"""Assume the non-format-specific state of message."""
|
| 1510 |
+
type_specific = getattr(message, '_type_specific_attributes', [])
|
| 1511 |
+
for name in message.__dict__:
|
| 1512 |
+
if name not in type_specific:
|
| 1513 |
+
self.__dict__[name] = message.__dict__[name]
|
| 1514 |
+
|
| 1515 |
+
def _explain_to(self, message):
|
| 1516 |
+
"""Copy format-specific state to message insofar as possible."""
|
| 1517 |
+
if isinstance(message, Message):
|
| 1518 |
+
return # There's nothing format-specific to explain.
|
| 1519 |
+
else:
|
| 1520 |
+
raise TypeError('Cannot convert to specified type')
|
| 1521 |
+
|
| 1522 |
+
|
| 1523 |
+
class MaildirMessage(Message):
|
| 1524 |
+
"""Message with Maildir-specific properties."""
|
| 1525 |
+
|
| 1526 |
+
_type_specific_attributes = ['_subdir', '_info', '_date']
|
| 1527 |
+
|
| 1528 |
+
def __init__(self, message=None):
|
| 1529 |
+
"""Initialize a MaildirMessage instance."""
|
| 1530 |
+
self._subdir = 'new'
|
| 1531 |
+
self._info = ''
|
| 1532 |
+
self._date = time.time()
|
| 1533 |
+
Message.__init__(self, message)
|
| 1534 |
+
|
| 1535 |
+
def get_subdir(self):
|
| 1536 |
+
"""Return 'new' or 'cur'."""
|
| 1537 |
+
return self._subdir
|
| 1538 |
+
|
| 1539 |
+
def set_subdir(self, subdir):
|
| 1540 |
+
"""Set subdir to 'new' or 'cur'."""
|
| 1541 |
+
if subdir == 'new' or subdir == 'cur':
|
| 1542 |
+
self._subdir = subdir
|
| 1543 |
+
else:
|
| 1544 |
+
raise ValueError("subdir must be 'new' or 'cur': %s" % subdir)
|
| 1545 |
+
|
| 1546 |
+
def get_flags(self):
|
| 1547 |
+
"""Return as a string the flags that are set."""
|
| 1548 |
+
if self._info.startswith('2,'):
|
| 1549 |
+
return self._info[2:]
|
| 1550 |
+
else:
|
| 1551 |
+
return ''
|
| 1552 |
+
|
| 1553 |
+
def set_flags(self, flags):
|
| 1554 |
+
"""Set the given flags and unset all others."""
|
| 1555 |
+
self._info = '2,' + ''.join(sorted(flags))
|
| 1556 |
+
|
| 1557 |
+
def add_flag(self, flag):
|
| 1558 |
+
"""Set the given flag(s) without changing others."""
|
| 1559 |
+
self.set_flags(''.join(set(self.get_flags()) | set(flag)))
|
| 1560 |
+
|
| 1561 |
+
def remove_flag(self, flag):
|
| 1562 |
+
"""Unset the given string flag(s) without changing others."""
|
| 1563 |
+
if self.get_flags():
|
| 1564 |
+
self.set_flags(''.join(set(self.get_flags()) - set(flag)))
|
| 1565 |
+
|
| 1566 |
+
def get_date(self):
|
| 1567 |
+
"""Return delivery date of message, in seconds since the epoch."""
|
| 1568 |
+
return self._date
|
| 1569 |
+
|
| 1570 |
+
def set_date(self, date):
|
| 1571 |
+
"""Set delivery date of message, in seconds since the epoch."""
|
| 1572 |
+
try:
|
| 1573 |
+
self._date = float(date)
|
| 1574 |
+
except ValueError:
|
| 1575 |
+
raise TypeError("can't convert to float: %s" % date) from None
|
| 1576 |
+
|
| 1577 |
+
def get_info(self):
|
| 1578 |
+
"""Get the message's "info" as a string."""
|
| 1579 |
+
return self._info
|
| 1580 |
+
|
| 1581 |
+
def set_info(self, info):
|
| 1582 |
+
"""Set the message's "info" string."""
|
| 1583 |
+
if isinstance(info, str):
|
| 1584 |
+
self._info = info
|
| 1585 |
+
else:
|
| 1586 |
+
raise TypeError('info must be a string: %s' % type(info))
|
| 1587 |
+
|
| 1588 |
+
def _explain_to(self, message):
|
| 1589 |
+
"""Copy Maildir-specific state to message insofar as possible."""
|
| 1590 |
+
if isinstance(message, MaildirMessage):
|
| 1591 |
+
message.set_flags(self.get_flags())
|
| 1592 |
+
message.set_subdir(self.get_subdir())
|
| 1593 |
+
message.set_date(self.get_date())
|
| 1594 |
+
elif isinstance(message, _mboxMMDFMessage):
|
| 1595 |
+
flags = set(self.get_flags())
|
| 1596 |
+
if 'S' in flags:
|
| 1597 |
+
message.add_flag('R')
|
| 1598 |
+
if self.get_subdir() == 'cur':
|
| 1599 |
+
message.add_flag('O')
|
| 1600 |
+
if 'T' in flags:
|
| 1601 |
+
message.add_flag('D')
|
| 1602 |
+
if 'F' in flags:
|
| 1603 |
+
message.add_flag('F')
|
| 1604 |
+
if 'R' in flags:
|
| 1605 |
+
message.add_flag('A')
|
| 1606 |
+
message.set_from('MAILER-DAEMON', time.gmtime(self.get_date()))
|
| 1607 |
+
elif isinstance(message, MHMessage):
|
| 1608 |
+
flags = set(self.get_flags())
|
| 1609 |
+
if 'S' not in flags:
|
| 1610 |
+
message.add_sequence('unseen')
|
| 1611 |
+
if 'R' in flags:
|
| 1612 |
+
message.add_sequence('replied')
|
| 1613 |
+
if 'F' in flags:
|
| 1614 |
+
message.add_sequence('flagged')
|
| 1615 |
+
elif isinstance(message, BabylMessage):
|
| 1616 |
+
flags = set(self.get_flags())
|
| 1617 |
+
if 'S' not in flags:
|
| 1618 |
+
message.add_label('unseen')
|
| 1619 |
+
if 'T' in flags:
|
| 1620 |
+
message.add_label('deleted')
|
| 1621 |
+
if 'R' in flags:
|
| 1622 |
+
message.add_label('answered')
|
| 1623 |
+
if 'P' in flags:
|
| 1624 |
+
message.add_label('forwarded')
|
| 1625 |
+
elif isinstance(message, Message):
|
| 1626 |
+
pass
|
| 1627 |
+
else:
|
| 1628 |
+
raise TypeError('Cannot convert to specified type: %s' %
|
| 1629 |
+
type(message))
|
| 1630 |
+
|
| 1631 |
+
|
| 1632 |
+
class _mboxMMDFMessage(Message):
|
| 1633 |
+
"""Message with mbox- or MMDF-specific properties."""
|
| 1634 |
+
|
| 1635 |
+
_type_specific_attributes = ['_from']
|
| 1636 |
+
|
| 1637 |
+
def __init__(self, message=None):
|
| 1638 |
+
"""Initialize an mboxMMDFMessage instance."""
|
| 1639 |
+
self.set_from('MAILER-DAEMON', True)
|
| 1640 |
+
if isinstance(message, email.message.Message):
|
| 1641 |
+
unixfrom = message.get_unixfrom()
|
| 1642 |
+
if unixfrom is not None and unixfrom.startswith('From '):
|
| 1643 |
+
self.set_from(unixfrom[5:])
|
| 1644 |
+
Message.__init__(self, message)
|
| 1645 |
+
|
| 1646 |
+
def get_from(self):
|
| 1647 |
+
"""Return contents of "From " line."""
|
| 1648 |
+
return self._from
|
| 1649 |
+
|
| 1650 |
+
def set_from(self, from_, time_=None):
|
| 1651 |
+
"""Set "From " line, formatting and appending time_ if specified."""
|
| 1652 |
+
if time_ is not None:
|
| 1653 |
+
if time_ is True:
|
| 1654 |
+
time_ = time.gmtime()
|
| 1655 |
+
from_ += ' ' + time.asctime(time_)
|
| 1656 |
+
self._from = from_
|
| 1657 |
+
|
| 1658 |
+
def get_flags(self):
|
| 1659 |
+
"""Return as a string the flags that are set."""
|
| 1660 |
+
return self.get('Status', '') + self.get('X-Status', '')
|
| 1661 |
+
|
| 1662 |
+
def set_flags(self, flags):
|
| 1663 |
+
"""Set the given flags and unset all others."""
|
| 1664 |
+
flags = set(flags)
|
| 1665 |
+
status_flags, xstatus_flags = '', ''
|
| 1666 |
+
for flag in ('R', 'O'):
|
| 1667 |
+
if flag in flags:
|
| 1668 |
+
status_flags += flag
|
| 1669 |
+
flags.remove(flag)
|
| 1670 |
+
for flag in ('D', 'F', 'A'):
|
| 1671 |
+
if flag in flags:
|
| 1672 |
+
xstatus_flags += flag
|
| 1673 |
+
flags.remove(flag)
|
| 1674 |
+
xstatus_flags += ''.join(sorted(flags))
|
| 1675 |
+
try:
|
| 1676 |
+
self.replace_header('Status', status_flags)
|
| 1677 |
+
except KeyError:
|
| 1678 |
+
self.add_header('Status', status_flags)
|
| 1679 |
+
try:
|
| 1680 |
+
self.replace_header('X-Status', xstatus_flags)
|
| 1681 |
+
except KeyError:
|
| 1682 |
+
self.add_header('X-Status', xstatus_flags)
|
| 1683 |
+
|
| 1684 |
+
def add_flag(self, flag):
|
| 1685 |
+
"""Set the given flag(s) without changing others."""
|
| 1686 |
+
self.set_flags(''.join(set(self.get_flags()) | set(flag)))
|
| 1687 |
+
|
| 1688 |
+
def remove_flag(self, flag):
|
| 1689 |
+
"""Unset the given string flag(s) without changing others."""
|
| 1690 |
+
if 'Status' in self or 'X-Status' in self:
|
| 1691 |
+
self.set_flags(''.join(set(self.get_flags()) - set(flag)))
|
| 1692 |
+
|
| 1693 |
+
def _explain_to(self, message):
|
| 1694 |
+
"""Copy mbox- or MMDF-specific state to message insofar as possible."""
|
| 1695 |
+
if isinstance(message, MaildirMessage):
|
| 1696 |
+
flags = set(self.get_flags())
|
| 1697 |
+
if 'O' in flags:
|
| 1698 |
+
message.set_subdir('cur')
|
| 1699 |
+
if 'F' in flags:
|
| 1700 |
+
message.add_flag('F')
|
| 1701 |
+
if 'A' in flags:
|
| 1702 |
+
message.add_flag('R')
|
| 1703 |
+
if 'R' in flags:
|
| 1704 |
+
message.add_flag('S')
|
| 1705 |
+
if 'D' in flags:
|
| 1706 |
+
message.add_flag('T')
|
| 1707 |
+
del message['status']
|
| 1708 |
+
del message['x-status']
|
| 1709 |
+
maybe_date = ' '.join(self.get_from().split()[-5:])
|
| 1710 |
+
try:
|
| 1711 |
+
message.set_date(calendar.timegm(time.strptime(maybe_date,
|
| 1712 |
+
'%a %b %d %H:%M:%S %Y')))
|
| 1713 |
+
except (ValueError, OverflowError):
|
| 1714 |
+
pass
|
| 1715 |
+
elif isinstance(message, _mboxMMDFMessage):
|
| 1716 |
+
message.set_flags(self.get_flags())
|
| 1717 |
+
message.set_from(self.get_from())
|
| 1718 |
+
elif isinstance(message, MHMessage):
|
| 1719 |
+
flags = set(self.get_flags())
|
| 1720 |
+
if 'R' not in flags:
|
| 1721 |
+
message.add_sequence('unseen')
|
| 1722 |
+
if 'A' in flags:
|
| 1723 |
+
message.add_sequence('replied')
|
| 1724 |
+
if 'F' in flags:
|
| 1725 |
+
message.add_sequence('flagged')
|
| 1726 |
+
del message['status']
|
| 1727 |
+
del message['x-status']
|
| 1728 |
+
elif isinstance(message, BabylMessage):
|
| 1729 |
+
flags = set(self.get_flags())
|
| 1730 |
+
if 'R' not in flags:
|
| 1731 |
+
message.add_label('unseen')
|
| 1732 |
+
if 'D' in flags:
|
| 1733 |
+
message.add_label('deleted')
|
| 1734 |
+
if 'A' in flags:
|
| 1735 |
+
message.add_label('answered')
|
| 1736 |
+
del message['status']
|
| 1737 |
+
del message['x-status']
|
| 1738 |
+
elif isinstance(message, Message):
|
| 1739 |
+
pass
|
| 1740 |
+
else:
|
| 1741 |
+
raise TypeError('Cannot convert to specified type: %s' %
|
| 1742 |
+
type(message))
|
| 1743 |
+
|
| 1744 |
+
|
| 1745 |
+
class mboxMessage(_mboxMMDFMessage):
|
| 1746 |
+
"""Message with mbox-specific properties."""
|
| 1747 |
+
|
| 1748 |
+
|
| 1749 |
+
class MHMessage(Message):
|
| 1750 |
+
"""Message with MH-specific properties."""
|
| 1751 |
+
|
| 1752 |
+
_type_specific_attributes = ['_sequences']
|
| 1753 |
+
|
| 1754 |
+
def __init__(self, message=None):
|
| 1755 |
+
"""Initialize an MHMessage instance."""
|
| 1756 |
+
self._sequences = []
|
| 1757 |
+
Message.__init__(self, message)
|
| 1758 |
+
|
| 1759 |
+
def get_sequences(self):
|
| 1760 |
+
"""Return a list of sequences that include the message."""
|
| 1761 |
+
return self._sequences[:]
|
| 1762 |
+
|
| 1763 |
+
def set_sequences(self, sequences):
|
| 1764 |
+
"""Set the list of sequences that include the message."""
|
| 1765 |
+
self._sequences = list(sequences)
|
| 1766 |
+
|
| 1767 |
+
def add_sequence(self, sequence):
|
| 1768 |
+
"""Add sequence to list of sequences including the message."""
|
| 1769 |
+
if isinstance(sequence, str):
|
| 1770 |
+
if not sequence in self._sequences:
|
| 1771 |
+
self._sequences.append(sequence)
|
| 1772 |
+
else:
|
| 1773 |
+
raise TypeError('sequence type must be str: %s' % type(sequence))
|
| 1774 |
+
|
| 1775 |
+
def remove_sequence(self, sequence):
|
| 1776 |
+
"""Remove sequence from the list of sequences including the message."""
|
| 1777 |
+
try:
|
| 1778 |
+
self._sequences.remove(sequence)
|
| 1779 |
+
except ValueError:
|
| 1780 |
+
pass
|
| 1781 |
+
|
| 1782 |
+
def _explain_to(self, message):
|
| 1783 |
+
"""Copy MH-specific state to message insofar as possible."""
|
| 1784 |
+
if isinstance(message, MaildirMessage):
|
| 1785 |
+
sequences = set(self.get_sequences())
|
| 1786 |
+
if 'unseen' in sequences:
|
| 1787 |
+
message.set_subdir('cur')
|
| 1788 |
+
else:
|
| 1789 |
+
message.set_subdir('cur')
|
| 1790 |
+
message.add_flag('S')
|
| 1791 |
+
if 'flagged' in sequences:
|
| 1792 |
+
message.add_flag('F')
|
| 1793 |
+
if 'replied' in sequences:
|
| 1794 |
+
message.add_flag('R')
|
| 1795 |
+
elif isinstance(message, _mboxMMDFMessage):
|
| 1796 |
+
sequences = set(self.get_sequences())
|
| 1797 |
+
if 'unseen' not in sequences:
|
| 1798 |
+
message.add_flag('RO')
|
| 1799 |
+
else:
|
| 1800 |
+
message.add_flag('O')
|
| 1801 |
+
if 'flagged' in sequences:
|
| 1802 |
+
message.add_flag('F')
|
| 1803 |
+
if 'replied' in sequences:
|
| 1804 |
+
message.add_flag('A')
|
| 1805 |
+
elif isinstance(message, MHMessage):
|
| 1806 |
+
for sequence in self.get_sequences():
|
| 1807 |
+
message.add_sequence(sequence)
|
| 1808 |
+
elif isinstance(message, BabylMessage):
|
| 1809 |
+
sequences = set(self.get_sequences())
|
| 1810 |
+
if 'unseen' in sequences:
|
| 1811 |
+
message.add_label('unseen')
|
| 1812 |
+
if 'replied' in sequences:
|
| 1813 |
+
message.add_label('answered')
|
| 1814 |
+
elif isinstance(message, Message):
|
| 1815 |
+
pass
|
| 1816 |
+
else:
|
| 1817 |
+
raise TypeError('Cannot convert to specified type: %s' %
|
| 1818 |
+
type(message))
|
| 1819 |
+
|
| 1820 |
+
|
| 1821 |
+
class BabylMessage(Message):
|
| 1822 |
+
"""Message with Babyl-specific properties."""
|
| 1823 |
+
|
| 1824 |
+
_type_specific_attributes = ['_labels', '_visible']
|
| 1825 |
+
|
| 1826 |
+
def __init__(self, message=None):
|
| 1827 |
+
"""Initialize a BabylMessage instance."""
|
| 1828 |
+
self._labels = []
|
| 1829 |
+
self._visible = Message()
|
| 1830 |
+
Message.__init__(self, message)
|
| 1831 |
+
|
| 1832 |
+
def get_labels(self):
|
| 1833 |
+
"""Return a list of labels on the message."""
|
| 1834 |
+
return self._labels[:]
|
| 1835 |
+
|
| 1836 |
+
def set_labels(self, labels):
|
| 1837 |
+
"""Set the list of labels on the message."""
|
| 1838 |
+
self._labels = list(labels)
|
| 1839 |
+
|
| 1840 |
+
def add_label(self, label):
|
| 1841 |
+
"""Add label to list of labels on the message."""
|
| 1842 |
+
if isinstance(label, str):
|
| 1843 |
+
if label not in self._labels:
|
| 1844 |
+
self._labels.append(label)
|
| 1845 |
+
else:
|
| 1846 |
+
raise TypeError('label must be a string: %s' % type(label))
|
| 1847 |
+
|
| 1848 |
+
def remove_label(self, label):
|
| 1849 |
+
"""Remove label from the list of labels on the message."""
|
| 1850 |
+
try:
|
| 1851 |
+
self._labels.remove(label)
|
| 1852 |
+
except ValueError:
|
| 1853 |
+
pass
|
| 1854 |
+
|
| 1855 |
+
def get_visible(self):
|
| 1856 |
+
"""Return a Message representation of visible headers."""
|
| 1857 |
+
return Message(self._visible)
|
| 1858 |
+
|
| 1859 |
+
def set_visible(self, visible):
|
| 1860 |
+
"""Set the Message representation of visible headers."""
|
| 1861 |
+
self._visible = Message(visible)
|
| 1862 |
+
|
| 1863 |
+
def update_visible(self):
|
| 1864 |
+
"""Update and/or sensibly generate a set of visible headers."""
|
| 1865 |
+
for header in self._visible.keys():
|
| 1866 |
+
if header in self:
|
| 1867 |
+
self._visible.replace_header(header, self[header])
|
| 1868 |
+
else:
|
| 1869 |
+
del self._visible[header]
|
| 1870 |
+
for header in ('Date', 'From', 'Reply-To', 'To', 'CC', 'Subject'):
|
| 1871 |
+
if header in self and header not in self._visible:
|
| 1872 |
+
self._visible[header] = self[header]
|
| 1873 |
+
|
| 1874 |
+
def _explain_to(self, message):
|
| 1875 |
+
"""Copy Babyl-specific state to message insofar as possible."""
|
| 1876 |
+
if isinstance(message, MaildirMessage):
|
| 1877 |
+
labels = set(self.get_labels())
|
| 1878 |
+
if 'unseen' in labels:
|
| 1879 |
+
message.set_subdir('cur')
|
| 1880 |
+
else:
|
| 1881 |
+
message.set_subdir('cur')
|
| 1882 |
+
message.add_flag('S')
|
| 1883 |
+
if 'forwarded' in labels or 'resent' in labels:
|
| 1884 |
+
message.add_flag('P')
|
| 1885 |
+
if 'answered' in labels:
|
| 1886 |
+
message.add_flag('R')
|
| 1887 |
+
if 'deleted' in labels:
|
| 1888 |
+
message.add_flag('T')
|
| 1889 |
+
elif isinstance(message, _mboxMMDFMessage):
|
| 1890 |
+
labels = set(self.get_labels())
|
| 1891 |
+
if 'unseen' not in labels:
|
| 1892 |
+
message.add_flag('RO')
|
| 1893 |
+
else:
|
| 1894 |
+
message.add_flag('O')
|
| 1895 |
+
if 'deleted' in labels:
|
| 1896 |
+
message.add_flag('D')
|
| 1897 |
+
if 'answered' in labels:
|
| 1898 |
+
message.add_flag('A')
|
| 1899 |
+
elif isinstance(message, MHMessage):
|
| 1900 |
+
labels = set(self.get_labels())
|
| 1901 |
+
if 'unseen' in labels:
|
| 1902 |
+
message.add_sequence('unseen')
|
| 1903 |
+
if 'answered' in labels:
|
| 1904 |
+
message.add_sequence('replied')
|
| 1905 |
+
elif isinstance(message, BabylMessage):
|
| 1906 |
+
message.set_visible(self.get_visible())
|
| 1907 |
+
for label in self.get_labels():
|
| 1908 |
+
message.add_label(label)
|
| 1909 |
+
elif isinstance(message, Message):
|
| 1910 |
+
pass
|
| 1911 |
+
else:
|
| 1912 |
+
raise TypeError('Cannot convert to specified type: %s' %
|
| 1913 |
+
type(message))
|
| 1914 |
+
|
| 1915 |
+
|
| 1916 |
+
class MMDFMessage(_mboxMMDFMessage):
|
| 1917 |
+
"""Message with MMDF-specific properties."""
|
| 1918 |
+
|
| 1919 |
+
|
| 1920 |
+
class _ProxyFile:
|
| 1921 |
+
"""A read-only wrapper of a file."""
|
| 1922 |
+
|
| 1923 |
+
def __init__(self, f, pos=None):
|
| 1924 |
+
"""Initialize a _ProxyFile."""
|
| 1925 |
+
self._file = f
|
| 1926 |
+
if pos is None:
|
| 1927 |
+
self._pos = f.tell()
|
| 1928 |
+
else:
|
| 1929 |
+
self._pos = pos
|
| 1930 |
+
|
| 1931 |
+
def read(self, size=None):
|
| 1932 |
+
"""Read bytes."""
|
| 1933 |
+
return self._read(size, self._file.read)
|
| 1934 |
+
|
| 1935 |
+
def read1(self, size=None):
|
| 1936 |
+
"""Read bytes."""
|
| 1937 |
+
return self._read(size, self._file.read1)
|
| 1938 |
+
|
| 1939 |
+
def readline(self, size=None):
|
| 1940 |
+
"""Read a line."""
|
| 1941 |
+
return self._read(size, self._file.readline)
|
| 1942 |
+
|
| 1943 |
+
def readlines(self, sizehint=None):
|
| 1944 |
+
"""Read multiple lines."""
|
| 1945 |
+
result = []
|
| 1946 |
+
for line in self:
|
| 1947 |
+
result.append(line)
|
| 1948 |
+
if sizehint is not None:
|
| 1949 |
+
sizehint -= len(line)
|
| 1950 |
+
if sizehint <= 0:
|
| 1951 |
+
break
|
| 1952 |
+
return result
|
| 1953 |
+
|
| 1954 |
+
def __iter__(self):
|
| 1955 |
+
"""Iterate over lines."""
|
| 1956 |
+
while True:
|
| 1957 |
+
line = self.readline()
|
| 1958 |
+
if not line:
|
| 1959 |
+
return
|
| 1960 |
+
yield line
|
| 1961 |
+
|
| 1962 |
+
def tell(self):
|
| 1963 |
+
"""Return the position."""
|
| 1964 |
+
return self._pos
|
| 1965 |
+
|
| 1966 |
+
def seek(self, offset, whence=0):
|
| 1967 |
+
"""Change position."""
|
| 1968 |
+
if whence == 1:
|
| 1969 |
+
self._file.seek(self._pos)
|
| 1970 |
+
self._file.seek(offset, whence)
|
| 1971 |
+
self._pos = self._file.tell()
|
| 1972 |
+
|
| 1973 |
+
def close(self):
|
| 1974 |
+
"""Close the file."""
|
| 1975 |
+
if hasattr(self, '_file'):
|
| 1976 |
+
try:
|
| 1977 |
+
if hasattr(self._file, 'close'):
|
| 1978 |
+
self._file.close()
|
| 1979 |
+
finally:
|
| 1980 |
+
del self._file
|
| 1981 |
+
|
| 1982 |
+
def _read(self, size, read_method):
|
| 1983 |
+
"""Read size bytes using read_method."""
|
| 1984 |
+
if size is None:
|
| 1985 |
+
size = -1
|
| 1986 |
+
self._file.seek(self._pos)
|
| 1987 |
+
result = read_method(size)
|
| 1988 |
+
self._pos = self._file.tell()
|
| 1989 |
+
return result
|
| 1990 |
+
|
| 1991 |
+
def __enter__(self):
|
| 1992 |
+
"""Context management protocol support."""
|
| 1993 |
+
return self
|
| 1994 |
+
|
| 1995 |
+
def __exit__(self, *exc):
|
| 1996 |
+
self.close()
|
| 1997 |
+
|
| 1998 |
+
def readable(self):
|
| 1999 |
+
return self._file.readable()
|
| 2000 |
+
|
| 2001 |
+
def writable(self):
|
| 2002 |
+
return self._file.writable()
|
| 2003 |
+
|
| 2004 |
+
def seekable(self):
|
| 2005 |
+
return self._file.seekable()
|
| 2006 |
+
|
| 2007 |
+
def flush(self):
|
| 2008 |
+
return self._file.flush()
|
| 2009 |
+
|
| 2010 |
+
@property
|
| 2011 |
+
def closed(self):
|
| 2012 |
+
if not hasattr(self, '_file'):
|
| 2013 |
+
return True
|
| 2014 |
+
if not hasattr(self._file, 'closed'):
|
| 2015 |
+
return False
|
| 2016 |
+
return self._file.closed
|
| 2017 |
+
|
| 2018 |
+
|
| 2019 |
+
class _PartialFile(_ProxyFile):
|
| 2020 |
+
"""A read-only wrapper of part of a file."""
|
| 2021 |
+
|
| 2022 |
+
def __init__(self, f, start=None, stop=None):
|
| 2023 |
+
"""Initialize a _PartialFile."""
|
| 2024 |
+
_ProxyFile.__init__(self, f, start)
|
| 2025 |
+
self._start = start
|
| 2026 |
+
self._stop = stop
|
| 2027 |
+
|
| 2028 |
+
def tell(self):
|
| 2029 |
+
"""Return the position with respect to start."""
|
| 2030 |
+
return _ProxyFile.tell(self) - self._start
|
| 2031 |
+
|
| 2032 |
+
def seek(self, offset, whence=0):
|
| 2033 |
+
"""Change position, possibly with respect to start or stop."""
|
| 2034 |
+
if whence == 0:
|
| 2035 |
+
self._pos = self._start
|
| 2036 |
+
whence = 1
|
| 2037 |
+
elif whence == 2:
|
| 2038 |
+
self._pos = self._stop
|
| 2039 |
+
whence = 1
|
| 2040 |
+
_ProxyFile.seek(self, offset, whence)
|
| 2041 |
+
|
| 2042 |
+
def _read(self, size, read_method):
|
| 2043 |
+
"""Read size bytes using read_method, honoring start and stop."""
|
| 2044 |
+
remaining = self._stop - self._pos
|
| 2045 |
+
if remaining <= 0:
|
| 2046 |
+
return b''
|
| 2047 |
+
if size is None or size < 0 or size > remaining:
|
| 2048 |
+
size = remaining
|
| 2049 |
+
return _ProxyFile._read(self, size, read_method)
|
| 2050 |
+
|
| 2051 |
+
def close(self):
|
| 2052 |
+
# do *not* close the underlying file object for partial files,
|
| 2053 |
+
# since it's global to the mailbox object
|
| 2054 |
+
if hasattr(self, '_file'):
|
| 2055 |
+
del self._file
|
| 2056 |
+
|
| 2057 |
+
|
| 2058 |
+
def _lock_file(f, dotlock=True):
|
| 2059 |
+
"""Lock file f using lockf and dot locking."""
|
| 2060 |
+
dotlock_done = False
|
| 2061 |
+
try:
|
| 2062 |
+
if fcntl:
|
| 2063 |
+
try:
|
| 2064 |
+
fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
| 2065 |
+
except OSError as e:
|
| 2066 |
+
if e.errno in (errno.EAGAIN, errno.EACCES, errno.EROFS):
|
| 2067 |
+
raise ExternalClashError('lockf: lock unavailable: %s' %
|
| 2068 |
+
f.name)
|
| 2069 |
+
else:
|
| 2070 |
+
raise
|
| 2071 |
+
if dotlock:
|
| 2072 |
+
try:
|
| 2073 |
+
pre_lock = _create_temporary(f.name + '.lock')
|
| 2074 |
+
pre_lock.close()
|
| 2075 |
+
except OSError as e:
|
| 2076 |
+
if e.errno in (errno.EACCES, errno.EROFS):
|
| 2077 |
+
return # Without write access, just skip dotlocking.
|
| 2078 |
+
else:
|
| 2079 |
+
raise
|
| 2080 |
+
try:
|
| 2081 |
+
try:
|
| 2082 |
+
os.link(pre_lock.name, f.name + '.lock')
|
| 2083 |
+
dotlock_done = True
|
| 2084 |
+
except (AttributeError, PermissionError):
|
| 2085 |
+
os.rename(pre_lock.name, f.name + '.lock')
|
| 2086 |
+
dotlock_done = True
|
| 2087 |
+
else:
|
| 2088 |
+
os.unlink(pre_lock.name)
|
| 2089 |
+
except FileExistsError:
|
| 2090 |
+
os.remove(pre_lock.name)
|
| 2091 |
+
raise ExternalClashError('dot lock unavailable: %s' %
|
| 2092 |
+
f.name)
|
| 2093 |
+
except:
|
| 2094 |
+
if fcntl:
|
| 2095 |
+
fcntl.lockf(f, fcntl.LOCK_UN)
|
| 2096 |
+
if dotlock_done:
|
| 2097 |
+
os.remove(f.name + '.lock')
|
| 2098 |
+
raise
|
| 2099 |
+
|
| 2100 |
+
def _unlock_file(f):
|
| 2101 |
+
"""Unlock file f using lockf and dot locking."""
|
| 2102 |
+
if fcntl:
|
| 2103 |
+
fcntl.lockf(f, fcntl.LOCK_UN)
|
| 2104 |
+
if os.path.exists(f.name + '.lock'):
|
| 2105 |
+
os.remove(f.name + '.lock')
|
| 2106 |
+
|
| 2107 |
+
def _create_carefully(path):
|
| 2108 |
+
"""Create a file if it doesn't exist and open for reading and writing."""
|
| 2109 |
+
fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0o666)
|
| 2110 |
+
try:
|
| 2111 |
+
return open(path, 'rb+')
|
| 2112 |
+
finally:
|
| 2113 |
+
os.close(fd)
|
| 2114 |
+
|
| 2115 |
+
def _create_temporary(path):
|
| 2116 |
+
"""Create a temp file based on path and open for reading and writing."""
|
| 2117 |
+
return _create_carefully('%s.%s.%s.%s' % (path, int(time.time()),
|
| 2118 |
+
socket.gethostname(),
|
| 2119 |
+
os.getpid()))
|
| 2120 |
+
|
| 2121 |
+
def _sync_flush(f):
|
| 2122 |
+
"""Ensure changes to file f are physically on disk."""
|
| 2123 |
+
f.flush()
|
| 2124 |
+
if hasattr(os, 'fsync'):
|
| 2125 |
+
os.fsync(f.fileno())
|
| 2126 |
+
|
| 2127 |
+
def _sync_close(f):
|
| 2128 |
+
"""Close file f, ensuring all changes are physically on disk."""
|
| 2129 |
+
_sync_flush(f)
|
| 2130 |
+
f.close()
|
| 2131 |
+
|
| 2132 |
+
|
| 2133 |
+
class Error(Exception):
|
| 2134 |
+
"""Raised for module-specific errors."""
|
| 2135 |
+
|
| 2136 |
+
class NoSuchMailboxError(Error):
|
| 2137 |
+
"""The specified mailbox does not exist and won't be created."""
|
| 2138 |
+
|
| 2139 |
+
class NotEmptyError(Error):
|
| 2140 |
+
"""The specified mailbox is not empty and deletion was requested."""
|
| 2141 |
+
|
| 2142 |
+
class ExternalClashError(Error):
|
| 2143 |
+
"""Another process caused an action to fail."""
|
| 2144 |
+
|
| 2145 |
+
class FormatError(Error):
|
| 2146 |
+
"""A file appears to have an invalid format."""
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/mimetypes.py
ADDED
|
@@ -0,0 +1,614 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Guess the MIME type of a file.
|
| 2 |
+
|
| 3 |
+
This module defines two useful functions:
|
| 4 |
+
|
| 5 |
+
guess_type(url, strict=True) -- guess the MIME type and encoding of a URL.
|
| 6 |
+
|
| 7 |
+
guess_extension(type, strict=True) -- guess the extension for a given MIME type.
|
| 8 |
+
|
| 9 |
+
It also contains the following, for tuning the behavior:
|
| 10 |
+
|
| 11 |
+
Data:
|
| 12 |
+
|
| 13 |
+
knownfiles -- list of files to parse
|
| 14 |
+
inited -- flag set when init() has been called
|
| 15 |
+
suffix_map -- dictionary mapping suffixes to suffixes
|
| 16 |
+
encodings_map -- dictionary mapping suffixes to encodings
|
| 17 |
+
types_map -- dictionary mapping suffixes to types
|
| 18 |
+
|
| 19 |
+
Functions:
|
| 20 |
+
|
| 21 |
+
init([files]) -- parse a list of files, default knownfiles (on Windows, the
|
| 22 |
+
default values are taken from the registry)
|
| 23 |
+
read_mime_types(file) -- parse one file, return a dictionary or None
|
| 24 |
+
"""
|
| 25 |
+
|
| 26 |
+
import os
|
| 27 |
+
import sys
|
| 28 |
+
import posixpath
|
| 29 |
+
import urllib.parse
|
| 30 |
+
try:
|
| 31 |
+
import winreg as _winreg
|
| 32 |
+
except ImportError:
|
| 33 |
+
_winreg = None
|
| 34 |
+
|
| 35 |
+
__all__ = [
|
| 36 |
+
"knownfiles", "inited", "MimeTypes",
|
| 37 |
+
"guess_type", "guess_all_extensions", "guess_extension",
|
| 38 |
+
"add_type", "init", "read_mime_types",
|
| 39 |
+
"suffix_map", "encodings_map", "types_map", "common_types"
|
| 40 |
+
]
|
| 41 |
+
|
| 42 |
+
knownfiles = [
|
| 43 |
+
"/etc/mime.types",
|
| 44 |
+
"/etc/httpd/mime.types", # Mac OS X
|
| 45 |
+
"/etc/httpd/conf/mime.types", # Apache
|
| 46 |
+
"/etc/apache/mime.types", # Apache 1
|
| 47 |
+
"/etc/apache2/mime.types", # Apache 2
|
| 48 |
+
"/usr/local/etc/httpd/conf/mime.types",
|
| 49 |
+
"/usr/local/lib/netscape/mime.types",
|
| 50 |
+
"/usr/local/etc/httpd/conf/mime.types", # Apache 1.2
|
| 51 |
+
"/usr/local/etc/mime.types", # Apache 1.3
|
| 52 |
+
]
|
| 53 |
+
|
| 54 |
+
inited = False
|
| 55 |
+
_db = None
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
class MimeTypes:
|
| 59 |
+
"""MIME-types datastore.
|
| 60 |
+
|
| 61 |
+
This datastore can handle information from mime.types-style files
|
| 62 |
+
and supports basic determination of MIME type from a filename or
|
| 63 |
+
URL, and can guess a reasonable extension given a MIME type.
|
| 64 |
+
"""
|
| 65 |
+
|
| 66 |
+
def __init__(self, filenames=(), strict=True):
|
| 67 |
+
if not inited:
|
| 68 |
+
init()
|
| 69 |
+
self.encodings_map = _encodings_map_default.copy()
|
| 70 |
+
self.suffix_map = _suffix_map_default.copy()
|
| 71 |
+
self.types_map = ({}, {}) # dict for (non-strict, strict)
|
| 72 |
+
self.types_map_inv = ({}, {})
|
| 73 |
+
for (ext, type) in _types_map_default.items():
|
| 74 |
+
self.add_type(type, ext, True)
|
| 75 |
+
for (ext, type) in _common_types_default.items():
|
| 76 |
+
self.add_type(type, ext, False)
|
| 77 |
+
for name in filenames:
|
| 78 |
+
self.read(name, strict)
|
| 79 |
+
|
| 80 |
+
def add_type(self, type, ext, strict=True):
|
| 81 |
+
"""Add a mapping between a type and an extension.
|
| 82 |
+
|
| 83 |
+
When the extension is already known, the new
|
| 84 |
+
type will replace the old one. When the type
|
| 85 |
+
is already known the extension will be added
|
| 86 |
+
to the list of known extensions.
|
| 87 |
+
|
| 88 |
+
If strict is true, information will be added to
|
| 89 |
+
list of standard types, else to the list of non-standard
|
| 90 |
+
types.
|
| 91 |
+
"""
|
| 92 |
+
self.types_map[strict][ext] = type
|
| 93 |
+
exts = self.types_map_inv[strict].setdefault(type, [])
|
| 94 |
+
if ext not in exts:
|
| 95 |
+
exts.append(ext)
|
| 96 |
+
|
| 97 |
+
def guess_type(self, url, strict=True):
|
| 98 |
+
"""Guess the type of a file which is either a URL or a path-like object.
|
| 99 |
+
|
| 100 |
+
Return value is a tuple (type, encoding) where type is None if
|
| 101 |
+
the type can't be guessed (no or unknown suffix) or a string
|
| 102 |
+
of the form type/subtype, usable for a MIME Content-type
|
| 103 |
+
header; and encoding is None for no encoding or the name of
|
| 104 |
+
the program used to encode (e.g. compress or gzip). The
|
| 105 |
+
mappings are table driven. Encoding suffixes are case
|
| 106 |
+
sensitive; type suffixes are first tried case sensitive, then
|
| 107 |
+
case insensitive.
|
| 108 |
+
|
| 109 |
+
The suffixes .tgz, .taz and .tz (case sensitive!) are all
|
| 110 |
+
mapped to '.tar.gz'. (This is table-driven too, using the
|
| 111 |
+
dictionary suffix_map.)
|
| 112 |
+
|
| 113 |
+
Optional `strict' argument when False adds a bunch of commonly found,
|
| 114 |
+
but non-standard types.
|
| 115 |
+
"""
|
| 116 |
+
url = os.fspath(url)
|
| 117 |
+
scheme, url = urllib.parse._splittype(url)
|
| 118 |
+
if scheme == 'data':
|
| 119 |
+
# syntax of data URLs:
|
| 120 |
+
# dataurl := "data:" [ mediatype ] [ ";base64" ] "," data
|
| 121 |
+
# mediatype := [ type "/" subtype ] *( ";" parameter )
|
| 122 |
+
# data := *urlchar
|
| 123 |
+
# parameter := attribute "=" value
|
| 124 |
+
# type/subtype defaults to "text/plain"
|
| 125 |
+
comma = url.find(',')
|
| 126 |
+
if comma < 0:
|
| 127 |
+
# bad data URL
|
| 128 |
+
return None, None
|
| 129 |
+
semi = url.find(';', 0, comma)
|
| 130 |
+
if semi >= 0:
|
| 131 |
+
type = url[:semi]
|
| 132 |
+
else:
|
| 133 |
+
type = url[:comma]
|
| 134 |
+
if '=' in type or '/' not in type:
|
| 135 |
+
type = 'text/plain'
|
| 136 |
+
return type, None # never compressed, so encoding is None
|
| 137 |
+
base, ext = posixpath.splitext(url)
|
| 138 |
+
while ext in self.suffix_map:
|
| 139 |
+
base, ext = posixpath.splitext(base + self.suffix_map[ext])
|
| 140 |
+
if ext in self.encodings_map:
|
| 141 |
+
encoding = self.encodings_map[ext]
|
| 142 |
+
base, ext = posixpath.splitext(base)
|
| 143 |
+
else:
|
| 144 |
+
encoding = None
|
| 145 |
+
types_map = self.types_map[True]
|
| 146 |
+
if ext in types_map:
|
| 147 |
+
return types_map[ext], encoding
|
| 148 |
+
elif ext.lower() in types_map:
|
| 149 |
+
return types_map[ext.lower()], encoding
|
| 150 |
+
elif strict:
|
| 151 |
+
return None, encoding
|
| 152 |
+
types_map = self.types_map[False]
|
| 153 |
+
if ext in types_map:
|
| 154 |
+
return types_map[ext], encoding
|
| 155 |
+
elif ext.lower() in types_map:
|
| 156 |
+
return types_map[ext.lower()], encoding
|
| 157 |
+
else:
|
| 158 |
+
return None, encoding
|
| 159 |
+
|
| 160 |
+
def guess_all_extensions(self, type, strict=True):
|
| 161 |
+
"""Guess the extensions for a file based on its MIME type.
|
| 162 |
+
|
| 163 |
+
Return value is a list of strings giving the possible filename
|
| 164 |
+
extensions, including the leading dot ('.'). The extension is not
|
| 165 |
+
guaranteed to have been associated with any particular data stream,
|
| 166 |
+
but would be mapped to the MIME type `type' by guess_type().
|
| 167 |
+
|
| 168 |
+
Optional `strict' argument when false adds a bunch of commonly found,
|
| 169 |
+
but non-standard types.
|
| 170 |
+
"""
|
| 171 |
+
type = type.lower()
|
| 172 |
+
extensions = self.types_map_inv[True].get(type, [])
|
| 173 |
+
if not strict:
|
| 174 |
+
for ext in self.types_map_inv[False].get(type, []):
|
| 175 |
+
if ext not in extensions:
|
| 176 |
+
extensions.append(ext)
|
| 177 |
+
return extensions
|
| 178 |
+
|
| 179 |
+
def guess_extension(self, type, strict=True):
|
| 180 |
+
"""Guess the extension for a file based on its MIME type.
|
| 181 |
+
|
| 182 |
+
Return value is a string giving a filename extension,
|
| 183 |
+
including the leading dot ('.'). The extension is not
|
| 184 |
+
guaranteed to have been associated with any particular data
|
| 185 |
+
stream, but would be mapped to the MIME type `type' by
|
| 186 |
+
guess_type(). If no extension can be guessed for `type', None
|
| 187 |
+
is returned.
|
| 188 |
+
|
| 189 |
+
Optional `strict' argument when false adds a bunch of commonly found,
|
| 190 |
+
but non-standard types.
|
| 191 |
+
"""
|
| 192 |
+
extensions = self.guess_all_extensions(type, strict)
|
| 193 |
+
if not extensions:
|
| 194 |
+
return None
|
| 195 |
+
return extensions[0]
|
| 196 |
+
|
| 197 |
+
def read(self, filename, strict=True):
|
| 198 |
+
"""
|
| 199 |
+
Read a single mime.types-format file, specified by pathname.
|
| 200 |
+
|
| 201 |
+
If strict is true, information will be added to
|
| 202 |
+
list of standard types, else to the list of non-standard
|
| 203 |
+
types.
|
| 204 |
+
"""
|
| 205 |
+
with open(filename, encoding='utf-8') as fp:
|
| 206 |
+
self.readfp(fp, strict)
|
| 207 |
+
|
| 208 |
+
def readfp(self, fp, strict=True):
|
| 209 |
+
"""
|
| 210 |
+
Read a single mime.types-format file.
|
| 211 |
+
|
| 212 |
+
If strict is true, information will be added to
|
| 213 |
+
list of standard types, else to the list of non-standard
|
| 214 |
+
types.
|
| 215 |
+
"""
|
| 216 |
+
while 1:
|
| 217 |
+
line = fp.readline()
|
| 218 |
+
if not line:
|
| 219 |
+
break
|
| 220 |
+
words = line.split()
|
| 221 |
+
for i in range(len(words)):
|
| 222 |
+
if words[i][0] == '#':
|
| 223 |
+
del words[i:]
|
| 224 |
+
break
|
| 225 |
+
if not words:
|
| 226 |
+
continue
|
| 227 |
+
type, suffixes = words[0], words[1:]
|
| 228 |
+
for suff in suffixes:
|
| 229 |
+
self.add_type(type, '.' + suff, strict)
|
| 230 |
+
|
| 231 |
+
def read_windows_registry(self, strict=True):
|
| 232 |
+
"""
|
| 233 |
+
Load the MIME types database from Windows registry.
|
| 234 |
+
|
| 235 |
+
If strict is true, information will be added to
|
| 236 |
+
list of standard types, else to the list of non-standard
|
| 237 |
+
types.
|
| 238 |
+
"""
|
| 239 |
+
|
| 240 |
+
# Windows only
|
| 241 |
+
if not _winreg:
|
| 242 |
+
return
|
| 243 |
+
|
| 244 |
+
def enum_types(mimedb):
|
| 245 |
+
i = 0
|
| 246 |
+
while True:
|
| 247 |
+
try:
|
| 248 |
+
ctype = _winreg.EnumKey(mimedb, i)
|
| 249 |
+
except OSError:
|
| 250 |
+
break
|
| 251 |
+
else:
|
| 252 |
+
if '\0' not in ctype:
|
| 253 |
+
yield ctype
|
| 254 |
+
i += 1
|
| 255 |
+
|
| 256 |
+
with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, '') as hkcr:
|
| 257 |
+
for subkeyname in enum_types(hkcr):
|
| 258 |
+
try:
|
| 259 |
+
with _winreg.OpenKey(hkcr, subkeyname) as subkey:
|
| 260 |
+
# Only check file extensions
|
| 261 |
+
if not subkeyname.startswith("."):
|
| 262 |
+
continue
|
| 263 |
+
# raises OSError if no 'Content Type' value
|
| 264 |
+
mimetype, datatype = _winreg.QueryValueEx(
|
| 265 |
+
subkey, 'Content Type')
|
| 266 |
+
if datatype != _winreg.REG_SZ:
|
| 267 |
+
continue
|
| 268 |
+
self.add_type(mimetype, subkeyname, strict)
|
| 269 |
+
except OSError:
|
| 270 |
+
continue
|
| 271 |
+
|
| 272 |
+
def guess_type(url, strict=True):
|
| 273 |
+
"""Guess the type of a file based on its URL.
|
| 274 |
+
|
| 275 |
+
Return value is a tuple (type, encoding) where type is None if the
|
| 276 |
+
type can't be guessed (no or unknown suffix) or a string of the
|
| 277 |
+
form type/subtype, usable for a MIME Content-type header; and
|
| 278 |
+
encoding is None for no encoding or the name of the program used
|
| 279 |
+
to encode (e.g. compress or gzip). The mappings are table
|
| 280 |
+
driven. Encoding suffixes are case sensitive; type suffixes are
|
| 281 |
+
first tried case sensitive, then case insensitive.
|
| 282 |
+
|
| 283 |
+
The suffixes .tgz, .taz and .tz (case sensitive!) are all mapped
|
| 284 |
+
to ".tar.gz". (This is table-driven too, using the dictionary
|
| 285 |
+
suffix_map).
|
| 286 |
+
|
| 287 |
+
Optional `strict' argument when false adds a bunch of commonly found, but
|
| 288 |
+
non-standard types.
|
| 289 |
+
"""
|
| 290 |
+
if _db is None:
|
| 291 |
+
init()
|
| 292 |
+
return _db.guess_type(url, strict)
|
| 293 |
+
|
| 294 |
+
|
| 295 |
+
def guess_all_extensions(type, strict=True):
|
| 296 |
+
"""Guess the extensions for a file based on its MIME type.
|
| 297 |
+
|
| 298 |
+
Return value is a list of strings giving the possible filename
|
| 299 |
+
extensions, including the leading dot ('.'). The extension is not
|
| 300 |
+
guaranteed to have been associated with any particular data
|
| 301 |
+
stream, but would be mapped to the MIME type `type' by
|
| 302 |
+
guess_type(). If no extension can be guessed for `type', None
|
| 303 |
+
is returned.
|
| 304 |
+
|
| 305 |
+
Optional `strict' argument when false adds a bunch of commonly found,
|
| 306 |
+
but non-standard types.
|
| 307 |
+
"""
|
| 308 |
+
if _db is None:
|
| 309 |
+
init()
|
| 310 |
+
return _db.guess_all_extensions(type, strict)
|
| 311 |
+
|
| 312 |
+
def guess_extension(type, strict=True):
|
| 313 |
+
"""Guess the extension for a file based on its MIME type.
|
| 314 |
+
|
| 315 |
+
Return value is a string giving a filename extension, including the
|
| 316 |
+
leading dot ('.'). The extension is not guaranteed to have been
|
| 317 |
+
associated with any particular data stream, but would be mapped to the
|
| 318 |
+
MIME type `type' by guess_type(). If no extension can be guessed for
|
| 319 |
+
`type', None is returned.
|
| 320 |
+
|
| 321 |
+
Optional `strict' argument when false adds a bunch of commonly found,
|
| 322 |
+
but non-standard types.
|
| 323 |
+
"""
|
| 324 |
+
if _db is None:
|
| 325 |
+
init()
|
| 326 |
+
return _db.guess_extension(type, strict)
|
| 327 |
+
|
| 328 |
+
def add_type(type, ext, strict=True):
|
| 329 |
+
"""Add a mapping between a type and an extension.
|
| 330 |
+
|
| 331 |
+
When the extension is already known, the new
|
| 332 |
+
type will replace the old one. When the type
|
| 333 |
+
is already known the extension will be added
|
| 334 |
+
to the list of known extensions.
|
| 335 |
+
|
| 336 |
+
If strict is true, information will be added to
|
| 337 |
+
list of standard types, else to the list of non-standard
|
| 338 |
+
types.
|
| 339 |
+
"""
|
| 340 |
+
if _db is None:
|
| 341 |
+
init()
|
| 342 |
+
return _db.add_type(type, ext, strict)
|
| 343 |
+
|
| 344 |
+
|
| 345 |
+
def init(files=None):
|
| 346 |
+
global suffix_map, types_map, encodings_map, common_types
|
| 347 |
+
global inited, _db
|
| 348 |
+
inited = True # so that MimeTypes.__init__() doesn't call us again
|
| 349 |
+
|
| 350 |
+
if files is None or _db is None:
|
| 351 |
+
db = MimeTypes()
|
| 352 |
+
if _winreg:
|
| 353 |
+
db.read_windows_registry()
|
| 354 |
+
|
| 355 |
+
if files is None:
|
| 356 |
+
files = knownfiles
|
| 357 |
+
else:
|
| 358 |
+
files = knownfiles + list(files)
|
| 359 |
+
else:
|
| 360 |
+
db = _db
|
| 361 |
+
|
| 362 |
+
for file in files:
|
| 363 |
+
if os.path.isfile(file):
|
| 364 |
+
db.read(file)
|
| 365 |
+
encodings_map = db.encodings_map
|
| 366 |
+
suffix_map = db.suffix_map
|
| 367 |
+
types_map = db.types_map[True]
|
| 368 |
+
common_types = db.types_map[False]
|
| 369 |
+
# Make the DB a global variable now that it is fully initialized
|
| 370 |
+
_db = db
|
| 371 |
+
|
| 372 |
+
|
| 373 |
+
def read_mime_types(file):
|
| 374 |
+
try:
|
| 375 |
+
f = open(file, encoding='utf-8')
|
| 376 |
+
except OSError:
|
| 377 |
+
return None
|
| 378 |
+
with f:
|
| 379 |
+
db = MimeTypes()
|
| 380 |
+
db.readfp(f, True)
|
| 381 |
+
return db.types_map[True]
|
| 382 |
+
|
| 383 |
+
|
| 384 |
+
def _default_mime_types():
|
| 385 |
+
global suffix_map, _suffix_map_default
|
| 386 |
+
global encodings_map, _encodings_map_default
|
| 387 |
+
global types_map, _types_map_default
|
| 388 |
+
global common_types, _common_types_default
|
| 389 |
+
|
| 390 |
+
suffix_map = _suffix_map_default = {
|
| 391 |
+
'.svgz': '.svg.gz',
|
| 392 |
+
'.tgz': '.tar.gz',
|
| 393 |
+
'.taz': '.tar.gz',
|
| 394 |
+
'.tz': '.tar.gz',
|
| 395 |
+
'.tbz2': '.tar.bz2',
|
| 396 |
+
'.txz': '.tar.xz',
|
| 397 |
+
}
|
| 398 |
+
|
| 399 |
+
encodings_map = _encodings_map_default = {
|
| 400 |
+
'.gz': 'gzip',
|
| 401 |
+
'.Z': 'compress',
|
| 402 |
+
'.bz2': 'bzip2',
|
| 403 |
+
'.xz': 'xz',
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
# Before adding new types, make sure they are either registered with IANA,
|
| 407 |
+
# at http://www.iana.org/assignments/media-types
|
| 408 |
+
# or extensions, i.e. using the x- prefix
|
| 409 |
+
|
| 410 |
+
# If you add to these, please keep them sorted by mime type.
|
| 411 |
+
# Make sure the entry with the preferred file extension for a particular mime type
|
| 412 |
+
# appears before any others of the same mimetype.
|
| 413 |
+
types_map = _types_map_default = {
|
| 414 |
+
'.js' : 'application/javascript',
|
| 415 |
+
'.mjs' : 'application/javascript',
|
| 416 |
+
'.json' : 'application/json',
|
| 417 |
+
'.webmanifest': 'application/manifest+json',
|
| 418 |
+
'.doc' : 'application/msword',
|
| 419 |
+
'.dot' : 'application/msword',
|
| 420 |
+
'.wiz' : 'application/msword',
|
| 421 |
+
'.bin' : 'application/octet-stream',
|
| 422 |
+
'.a' : 'application/octet-stream',
|
| 423 |
+
'.dll' : 'application/octet-stream',
|
| 424 |
+
'.exe' : 'application/octet-stream',
|
| 425 |
+
'.o' : 'application/octet-stream',
|
| 426 |
+
'.obj' : 'application/octet-stream',
|
| 427 |
+
'.so' : 'application/octet-stream',
|
| 428 |
+
'.oda' : 'application/oda',
|
| 429 |
+
'.pdf' : 'application/pdf',
|
| 430 |
+
'.p7c' : 'application/pkcs7-mime',
|
| 431 |
+
'.ps' : 'application/postscript',
|
| 432 |
+
'.ai' : 'application/postscript',
|
| 433 |
+
'.eps' : 'application/postscript',
|
| 434 |
+
'.m3u' : 'application/vnd.apple.mpegurl',
|
| 435 |
+
'.m3u8' : 'application/vnd.apple.mpegurl',
|
| 436 |
+
'.xls' : 'application/vnd.ms-excel',
|
| 437 |
+
'.xlb' : 'application/vnd.ms-excel',
|
| 438 |
+
'.ppt' : 'application/vnd.ms-powerpoint',
|
| 439 |
+
'.pot' : 'application/vnd.ms-powerpoint',
|
| 440 |
+
'.ppa' : 'application/vnd.ms-powerpoint',
|
| 441 |
+
'.pps' : 'application/vnd.ms-powerpoint',
|
| 442 |
+
'.pwz' : 'application/vnd.ms-powerpoint',
|
| 443 |
+
'.wasm' : 'application/wasm',
|
| 444 |
+
'.bcpio' : 'application/x-bcpio',
|
| 445 |
+
'.cpio' : 'application/x-cpio',
|
| 446 |
+
'.csh' : 'application/x-csh',
|
| 447 |
+
'.dvi' : 'application/x-dvi',
|
| 448 |
+
'.gtar' : 'application/x-gtar',
|
| 449 |
+
'.hdf' : 'application/x-hdf',
|
| 450 |
+
'.h5' : 'application/x-hdf5',
|
| 451 |
+
'.latex' : 'application/x-latex',
|
| 452 |
+
'.mif' : 'application/x-mif',
|
| 453 |
+
'.cdf' : 'application/x-netcdf',
|
| 454 |
+
'.nc' : 'application/x-netcdf',
|
| 455 |
+
'.p12' : 'application/x-pkcs12',
|
| 456 |
+
'.pfx' : 'application/x-pkcs12',
|
| 457 |
+
'.ram' : 'application/x-pn-realaudio',
|
| 458 |
+
'.pyc' : 'application/x-python-code',
|
| 459 |
+
'.pyo' : 'application/x-python-code',
|
| 460 |
+
'.sh' : 'application/x-sh',
|
| 461 |
+
'.shar' : 'application/x-shar',
|
| 462 |
+
'.swf' : 'application/x-shockwave-flash',
|
| 463 |
+
'.sv4cpio': 'application/x-sv4cpio',
|
| 464 |
+
'.sv4crc' : 'application/x-sv4crc',
|
| 465 |
+
'.tar' : 'application/x-tar',
|
| 466 |
+
'.tcl' : 'application/x-tcl',
|
| 467 |
+
'.tex' : 'application/x-tex',
|
| 468 |
+
'.texi' : 'application/x-texinfo',
|
| 469 |
+
'.texinfo': 'application/x-texinfo',
|
| 470 |
+
'.roff' : 'application/x-troff',
|
| 471 |
+
'.t' : 'application/x-troff',
|
| 472 |
+
'.tr' : 'application/x-troff',
|
| 473 |
+
'.man' : 'application/x-troff-man',
|
| 474 |
+
'.me' : 'application/x-troff-me',
|
| 475 |
+
'.ms' : 'application/x-troff-ms',
|
| 476 |
+
'.ustar' : 'application/x-ustar',
|
| 477 |
+
'.src' : 'application/x-wais-source',
|
| 478 |
+
'.xsl' : 'application/xml',
|
| 479 |
+
'.rdf' : 'application/xml',
|
| 480 |
+
'.wsdl' : 'application/xml',
|
| 481 |
+
'.xpdl' : 'application/xml',
|
| 482 |
+
'.zip' : 'application/zip',
|
| 483 |
+
'.au' : 'audio/basic',
|
| 484 |
+
'.snd' : 'audio/basic',
|
| 485 |
+
'.mp3' : 'audio/mpeg',
|
| 486 |
+
'.mp2' : 'audio/mpeg',
|
| 487 |
+
'.aif' : 'audio/x-aiff',
|
| 488 |
+
'.aifc' : 'audio/x-aiff',
|
| 489 |
+
'.aiff' : 'audio/x-aiff',
|
| 490 |
+
'.ra' : 'audio/x-pn-realaudio',
|
| 491 |
+
'.wav' : 'audio/x-wav',
|
| 492 |
+
'.bmp' : 'image/bmp',
|
| 493 |
+
'.gif' : 'image/gif',
|
| 494 |
+
'.ief' : 'image/ief',
|
| 495 |
+
'.jpg' : 'image/jpeg',
|
| 496 |
+
'.jpe' : 'image/jpeg',
|
| 497 |
+
'.jpeg' : 'image/jpeg',
|
| 498 |
+
'.png' : 'image/png',
|
| 499 |
+
'.svg' : 'image/svg+xml',
|
| 500 |
+
'.tiff' : 'image/tiff',
|
| 501 |
+
'.tif' : 'image/tiff',
|
| 502 |
+
'.ico' : 'image/vnd.microsoft.icon',
|
| 503 |
+
'.ras' : 'image/x-cmu-raster',
|
| 504 |
+
'.bmp' : 'image/x-ms-bmp',
|
| 505 |
+
'.pnm' : 'image/x-portable-anymap',
|
| 506 |
+
'.pbm' : 'image/x-portable-bitmap',
|
| 507 |
+
'.pgm' : 'image/x-portable-graymap',
|
| 508 |
+
'.ppm' : 'image/x-portable-pixmap',
|
| 509 |
+
'.rgb' : 'image/x-rgb',
|
| 510 |
+
'.xbm' : 'image/x-xbitmap',
|
| 511 |
+
'.xpm' : 'image/x-xpixmap',
|
| 512 |
+
'.xwd' : 'image/x-xwindowdump',
|
| 513 |
+
'.eml' : 'message/rfc822',
|
| 514 |
+
'.mht' : 'message/rfc822',
|
| 515 |
+
'.mhtml' : 'message/rfc822',
|
| 516 |
+
'.nws' : 'message/rfc822',
|
| 517 |
+
'.css' : 'text/css',
|
| 518 |
+
'.csv' : 'text/csv',
|
| 519 |
+
'.html' : 'text/html',
|
| 520 |
+
'.htm' : 'text/html',
|
| 521 |
+
'.txt' : 'text/plain',
|
| 522 |
+
'.bat' : 'text/plain',
|
| 523 |
+
'.c' : 'text/plain',
|
| 524 |
+
'.h' : 'text/plain',
|
| 525 |
+
'.ksh' : 'text/plain',
|
| 526 |
+
'.pl' : 'text/plain',
|
| 527 |
+
'.rtx' : 'text/richtext',
|
| 528 |
+
'.tsv' : 'text/tab-separated-values',
|
| 529 |
+
'.py' : 'text/x-python',
|
| 530 |
+
'.etx' : 'text/x-setext',
|
| 531 |
+
'.sgm' : 'text/x-sgml',
|
| 532 |
+
'.sgml' : 'text/x-sgml',
|
| 533 |
+
'.vcf' : 'text/x-vcard',
|
| 534 |
+
'.xml' : 'text/xml',
|
| 535 |
+
'.mp4' : 'video/mp4',
|
| 536 |
+
'.mpeg' : 'video/mpeg',
|
| 537 |
+
'.m1v' : 'video/mpeg',
|
| 538 |
+
'.mpa' : 'video/mpeg',
|
| 539 |
+
'.mpe' : 'video/mpeg',
|
| 540 |
+
'.mpg' : 'video/mpeg',
|
| 541 |
+
'.mov' : 'video/quicktime',
|
| 542 |
+
'.qt' : 'video/quicktime',
|
| 543 |
+
'.webm' : 'video/webm',
|
| 544 |
+
'.avi' : 'video/x-msvideo',
|
| 545 |
+
'.movie' : 'video/x-sgi-movie',
|
| 546 |
+
}
|
| 547 |
+
|
| 548 |
+
# These are non-standard types, commonly found in the wild. They will
|
| 549 |
+
# only match if strict=0 flag is given to the API methods.
|
| 550 |
+
|
| 551 |
+
# Please sort these too
|
| 552 |
+
common_types = _common_types_default = {
|
| 553 |
+
'.rtf' : 'application/rtf',
|
| 554 |
+
'.midi': 'audio/midi',
|
| 555 |
+
'.mid' : 'audio/midi',
|
| 556 |
+
'.jpg' : 'image/jpg',
|
| 557 |
+
'.pict': 'image/pict',
|
| 558 |
+
'.pct' : 'image/pict',
|
| 559 |
+
'.pic' : 'image/pict',
|
| 560 |
+
'.xul' : 'text/xul',
|
| 561 |
+
}
|
| 562 |
+
|
| 563 |
+
|
| 564 |
+
_default_mime_types()
|
| 565 |
+
|
| 566 |
+
|
| 567 |
+
def _main():
|
| 568 |
+
import getopt
|
| 569 |
+
|
| 570 |
+
USAGE = """\
|
| 571 |
+
Usage: mimetypes.py [options] type
|
| 572 |
+
|
| 573 |
+
Options:
|
| 574 |
+
--help / -h -- print this message and exit
|
| 575 |
+
--lenient / -l -- additionally search of some common, but non-standard
|
| 576 |
+
types.
|
| 577 |
+
--extension / -e -- guess extension instead of type
|
| 578 |
+
|
| 579 |
+
More than one type argument may be given.
|
| 580 |
+
"""
|
| 581 |
+
|
| 582 |
+
def usage(code, msg=''):
|
| 583 |
+
print(USAGE)
|
| 584 |
+
if msg: print(msg)
|
| 585 |
+
sys.exit(code)
|
| 586 |
+
|
| 587 |
+
try:
|
| 588 |
+
opts, args = getopt.getopt(sys.argv[1:], 'hle',
|
| 589 |
+
['help', 'lenient', 'extension'])
|
| 590 |
+
except getopt.error as msg:
|
| 591 |
+
usage(1, msg)
|
| 592 |
+
|
| 593 |
+
strict = 1
|
| 594 |
+
extension = 0
|
| 595 |
+
for opt, arg in opts:
|
| 596 |
+
if opt in ('-h', '--help'):
|
| 597 |
+
usage(0)
|
| 598 |
+
elif opt in ('-l', '--lenient'):
|
| 599 |
+
strict = 0
|
| 600 |
+
elif opt in ('-e', '--extension'):
|
| 601 |
+
extension = 1
|
| 602 |
+
for gtype in args:
|
| 603 |
+
if extension:
|
| 604 |
+
guess = guess_extension(gtype, strict)
|
| 605 |
+
if not guess: print("I don't know anything about type", gtype)
|
| 606 |
+
else: print(guess)
|
| 607 |
+
else:
|
| 608 |
+
guess, encoding = guess_type(gtype, strict)
|
| 609 |
+
if not guess: print("I don't know anything about type", gtype)
|
| 610 |
+
else: print('type:', guess, 'encoding:', encoding)
|
| 611 |
+
|
| 612 |
+
|
| 613 |
+
if __name__ == '__main__':
|
| 614 |
+
_main()
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/modulefinder.py
ADDED
|
@@ -0,0 +1,687 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Find modules used by a script, using introspection."""
|
| 2 |
+
|
| 3 |
+
import dis
|
| 4 |
+
import importlib._bootstrap_external
|
| 5 |
+
import importlib.machinery
|
| 6 |
+
import marshal
|
| 7 |
+
import os
|
| 8 |
+
import io
|
| 9 |
+
import sys
|
| 10 |
+
import types
|
| 11 |
+
import warnings
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
LOAD_CONST = dis.opmap['LOAD_CONST']
|
| 15 |
+
IMPORT_NAME = dis.opmap['IMPORT_NAME']
|
| 16 |
+
STORE_NAME = dis.opmap['STORE_NAME']
|
| 17 |
+
STORE_GLOBAL = dis.opmap['STORE_GLOBAL']
|
| 18 |
+
STORE_OPS = STORE_NAME, STORE_GLOBAL
|
| 19 |
+
EXTENDED_ARG = dis.EXTENDED_ARG
|
| 20 |
+
|
| 21 |
+
# Old imp constants:
|
| 22 |
+
|
| 23 |
+
_SEARCH_ERROR = 0
|
| 24 |
+
_PY_SOURCE = 1
|
| 25 |
+
_PY_COMPILED = 2
|
| 26 |
+
_C_EXTENSION = 3
|
| 27 |
+
_PKG_DIRECTORY = 5
|
| 28 |
+
_C_BUILTIN = 6
|
| 29 |
+
_PY_FROZEN = 7
|
| 30 |
+
|
| 31 |
+
# Modulefinder does a good job at simulating Python's, but it can not
|
| 32 |
+
# handle __path__ modifications packages make at runtime. Therefore there
|
| 33 |
+
# is a mechanism whereby you can register extra paths in this map for a
|
| 34 |
+
# package, and it will be honored.
|
| 35 |
+
|
| 36 |
+
# Note this is a mapping is lists of paths.
|
| 37 |
+
packagePathMap = {}
|
| 38 |
+
|
| 39 |
+
# A Public interface
|
| 40 |
+
def AddPackagePath(packagename, path):
|
| 41 |
+
packagePathMap.setdefault(packagename, []).append(path)
|
| 42 |
+
|
| 43 |
+
replacePackageMap = {}
|
| 44 |
+
|
| 45 |
+
# This ReplacePackage mechanism allows modulefinder to work around
|
| 46 |
+
# situations in which a package injects itself under the name
|
| 47 |
+
# of another package into sys.modules at runtime by calling
|
| 48 |
+
# ReplacePackage("real_package_name", "faked_package_name")
|
| 49 |
+
# before running ModuleFinder.
|
| 50 |
+
|
| 51 |
+
def ReplacePackage(oldname, newname):
|
| 52 |
+
replacePackageMap[oldname] = newname
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def _find_module(name, path=None):
|
| 56 |
+
"""An importlib reimplementation of imp.find_module (for our purposes)."""
|
| 57 |
+
|
| 58 |
+
# It's necessary to clear the caches for our Finder first, in case any
|
| 59 |
+
# modules are being added/deleted/modified at runtime. In particular,
|
| 60 |
+
# test_modulefinder.py changes file tree contents in a cache-breaking way:
|
| 61 |
+
|
| 62 |
+
importlib.machinery.PathFinder.invalidate_caches()
|
| 63 |
+
|
| 64 |
+
spec = importlib.machinery.PathFinder.find_spec(name, path)
|
| 65 |
+
|
| 66 |
+
if spec is None:
|
| 67 |
+
raise ImportError("No module named {name!r}".format(name=name), name=name)
|
| 68 |
+
|
| 69 |
+
# Some special cases:
|
| 70 |
+
|
| 71 |
+
if spec.loader is importlib.machinery.BuiltinImporter:
|
| 72 |
+
return None, None, ("", "", _C_BUILTIN)
|
| 73 |
+
|
| 74 |
+
if spec.loader is importlib.machinery.FrozenImporter:
|
| 75 |
+
return None, None, ("", "", _PY_FROZEN)
|
| 76 |
+
|
| 77 |
+
file_path = spec.origin
|
| 78 |
+
|
| 79 |
+
if spec.loader.is_package(name):
|
| 80 |
+
return None, os.path.dirname(file_path), ("", "", _PKG_DIRECTORY)
|
| 81 |
+
|
| 82 |
+
if isinstance(spec.loader, importlib.machinery.SourceFileLoader):
|
| 83 |
+
kind = _PY_SOURCE
|
| 84 |
+
|
| 85 |
+
elif isinstance(spec.loader, importlib.machinery.ExtensionFileLoader):
|
| 86 |
+
kind = _C_EXTENSION
|
| 87 |
+
|
| 88 |
+
elif isinstance(spec.loader, importlib.machinery.SourcelessFileLoader):
|
| 89 |
+
kind = _PY_COMPILED
|
| 90 |
+
|
| 91 |
+
else: # Should never happen.
|
| 92 |
+
return None, None, ("", "", _SEARCH_ERROR)
|
| 93 |
+
|
| 94 |
+
file = io.open_code(file_path)
|
| 95 |
+
suffix = os.path.splitext(file_path)[-1]
|
| 96 |
+
|
| 97 |
+
return file, file_path, (suffix, "rb", kind)
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
class Module:
|
| 101 |
+
|
| 102 |
+
def __init__(self, name, file=None, path=None):
|
| 103 |
+
self.__name__ = name
|
| 104 |
+
self.__file__ = file
|
| 105 |
+
self.__path__ = path
|
| 106 |
+
self.__code__ = None
|
| 107 |
+
# The set of global names that are assigned to in the module.
|
| 108 |
+
# This includes those names imported through starimports of
|
| 109 |
+
# Python modules.
|
| 110 |
+
self.globalnames = {}
|
| 111 |
+
# The set of starimports this module did that could not be
|
| 112 |
+
# resolved, ie. a starimport from a non-Python module.
|
| 113 |
+
self.starimports = {}
|
| 114 |
+
|
| 115 |
+
def __repr__(self):
|
| 116 |
+
s = "Module(%r" % (self.__name__,)
|
| 117 |
+
if self.__file__ is not None:
|
| 118 |
+
s = s + ", %r" % (self.__file__,)
|
| 119 |
+
if self.__path__ is not None:
|
| 120 |
+
s = s + ", %r" % (self.__path__,)
|
| 121 |
+
s = s + ")"
|
| 122 |
+
return s
|
| 123 |
+
|
| 124 |
+
class ModuleFinder:
|
| 125 |
+
|
| 126 |
+
def __init__(self, path=None, debug=0, excludes=None, replace_paths=None):
|
| 127 |
+
if path is None:
|
| 128 |
+
path = sys.path
|
| 129 |
+
self.path = path
|
| 130 |
+
self.modules = {}
|
| 131 |
+
self.badmodules = {}
|
| 132 |
+
self.debug = debug
|
| 133 |
+
self.indent = 0
|
| 134 |
+
self.excludes = excludes if excludes is not None else []
|
| 135 |
+
self.replace_paths = replace_paths if replace_paths is not None else []
|
| 136 |
+
self.processed_paths = [] # Used in debugging only
|
| 137 |
+
|
| 138 |
+
def msg(self, level, str, *args):
|
| 139 |
+
if level <= self.debug:
|
| 140 |
+
for i in range(self.indent):
|
| 141 |
+
print(" ", end=' ')
|
| 142 |
+
print(str, end=' ')
|
| 143 |
+
for arg in args:
|
| 144 |
+
print(repr(arg), end=' ')
|
| 145 |
+
print()
|
| 146 |
+
|
| 147 |
+
def msgin(self, *args):
|
| 148 |
+
level = args[0]
|
| 149 |
+
if level <= self.debug:
|
| 150 |
+
self.indent = self.indent + 1
|
| 151 |
+
self.msg(*args)
|
| 152 |
+
|
| 153 |
+
def msgout(self, *args):
|
| 154 |
+
level = args[0]
|
| 155 |
+
if level <= self.debug:
|
| 156 |
+
self.indent = self.indent - 1
|
| 157 |
+
self.msg(*args)
|
| 158 |
+
|
| 159 |
+
def run_script(self, pathname):
|
| 160 |
+
self.msg(2, "run_script", pathname)
|
| 161 |
+
with io.open_code(pathname) as fp:
|
| 162 |
+
stuff = ("", "rb", _PY_SOURCE)
|
| 163 |
+
self.load_module('__main__', fp, pathname, stuff)
|
| 164 |
+
|
| 165 |
+
def load_file(self, pathname):
|
| 166 |
+
dir, name = os.path.split(pathname)
|
| 167 |
+
name, ext = os.path.splitext(name)
|
| 168 |
+
with io.open_code(pathname) as fp:
|
| 169 |
+
stuff = (ext, "rb", _PY_SOURCE)
|
| 170 |
+
self.load_module(name, fp, pathname, stuff)
|
| 171 |
+
|
| 172 |
+
def import_hook(self, name, caller=None, fromlist=None, level=-1):
|
| 173 |
+
self.msg(3, "import_hook", name, caller, fromlist, level)
|
| 174 |
+
parent = self.determine_parent(caller, level=level)
|
| 175 |
+
q, tail = self.find_head_package(parent, name)
|
| 176 |
+
m = self.load_tail(q, tail)
|
| 177 |
+
if not fromlist:
|
| 178 |
+
return q
|
| 179 |
+
if m.__path__:
|
| 180 |
+
self.ensure_fromlist(m, fromlist)
|
| 181 |
+
return None
|
| 182 |
+
|
| 183 |
+
def determine_parent(self, caller, level=-1):
|
| 184 |
+
self.msgin(4, "determine_parent", caller, level)
|
| 185 |
+
if not caller or level == 0:
|
| 186 |
+
self.msgout(4, "determine_parent -> None")
|
| 187 |
+
return None
|
| 188 |
+
pname = caller.__name__
|
| 189 |
+
if level >= 1: # relative import
|
| 190 |
+
if caller.__path__:
|
| 191 |
+
level -= 1
|
| 192 |
+
if level == 0:
|
| 193 |
+
parent = self.modules[pname]
|
| 194 |
+
assert parent is caller
|
| 195 |
+
self.msgout(4, "determine_parent ->", parent)
|
| 196 |
+
return parent
|
| 197 |
+
if pname.count(".") < level:
|
| 198 |
+
raise ImportError("relative importpath too deep")
|
| 199 |
+
pname = ".".join(pname.split(".")[:-level])
|
| 200 |
+
parent = self.modules[pname]
|
| 201 |
+
self.msgout(4, "determine_parent ->", parent)
|
| 202 |
+
return parent
|
| 203 |
+
if caller.__path__:
|
| 204 |
+
parent = self.modules[pname]
|
| 205 |
+
assert caller is parent
|
| 206 |
+
self.msgout(4, "determine_parent ->", parent)
|
| 207 |
+
return parent
|
| 208 |
+
if '.' in pname:
|
| 209 |
+
i = pname.rfind('.')
|
| 210 |
+
pname = pname[:i]
|
| 211 |
+
parent = self.modules[pname]
|
| 212 |
+
assert parent.__name__ == pname
|
| 213 |
+
self.msgout(4, "determine_parent ->", parent)
|
| 214 |
+
return parent
|
| 215 |
+
self.msgout(4, "determine_parent -> None")
|
| 216 |
+
return None
|
| 217 |
+
|
| 218 |
+
def find_head_package(self, parent, name):
|
| 219 |
+
self.msgin(4, "find_head_package", parent, name)
|
| 220 |
+
if '.' in name:
|
| 221 |
+
i = name.find('.')
|
| 222 |
+
head = name[:i]
|
| 223 |
+
tail = name[i+1:]
|
| 224 |
+
else:
|
| 225 |
+
head = name
|
| 226 |
+
tail = ""
|
| 227 |
+
if parent:
|
| 228 |
+
qname = "%s.%s" % (parent.__name__, head)
|
| 229 |
+
else:
|
| 230 |
+
qname = head
|
| 231 |
+
q = self.import_module(head, qname, parent)
|
| 232 |
+
if q:
|
| 233 |
+
self.msgout(4, "find_head_package ->", (q, tail))
|
| 234 |
+
return q, tail
|
| 235 |
+
if parent:
|
| 236 |
+
qname = head
|
| 237 |
+
parent = None
|
| 238 |
+
q = self.import_module(head, qname, parent)
|
| 239 |
+
if q:
|
| 240 |
+
self.msgout(4, "find_head_package ->", (q, tail))
|
| 241 |
+
return q, tail
|
| 242 |
+
self.msgout(4, "raise ImportError: No module named", qname)
|
| 243 |
+
raise ImportError("No module named " + qname)
|
| 244 |
+
|
| 245 |
+
def load_tail(self, q, tail):
|
| 246 |
+
self.msgin(4, "load_tail", q, tail)
|
| 247 |
+
m = q
|
| 248 |
+
while tail:
|
| 249 |
+
i = tail.find('.')
|
| 250 |
+
if i < 0: i = len(tail)
|
| 251 |
+
head, tail = tail[:i], tail[i+1:]
|
| 252 |
+
mname = "%s.%s" % (m.__name__, head)
|
| 253 |
+
m = self.import_module(head, mname, m)
|
| 254 |
+
if not m:
|
| 255 |
+
self.msgout(4, "raise ImportError: No module named", mname)
|
| 256 |
+
raise ImportError("No module named " + mname)
|
| 257 |
+
self.msgout(4, "load_tail ->", m)
|
| 258 |
+
return m
|
| 259 |
+
|
| 260 |
+
def ensure_fromlist(self, m, fromlist, recursive=0):
|
| 261 |
+
self.msg(4, "ensure_fromlist", m, fromlist, recursive)
|
| 262 |
+
for sub in fromlist:
|
| 263 |
+
if sub == "*":
|
| 264 |
+
if not recursive:
|
| 265 |
+
all = self.find_all_submodules(m)
|
| 266 |
+
if all:
|
| 267 |
+
self.ensure_fromlist(m, all, 1)
|
| 268 |
+
elif not hasattr(m, sub):
|
| 269 |
+
subname = "%s.%s" % (m.__name__, sub)
|
| 270 |
+
submod = self.import_module(sub, subname, m)
|
| 271 |
+
if not submod:
|
| 272 |
+
raise ImportError("No module named " + subname)
|
| 273 |
+
|
| 274 |
+
def find_all_submodules(self, m):
|
| 275 |
+
if not m.__path__:
|
| 276 |
+
return
|
| 277 |
+
modules = {}
|
| 278 |
+
# 'suffixes' used to be a list hardcoded to [".py", ".pyc"].
|
| 279 |
+
# But we must also collect Python extension modules - although
|
| 280 |
+
# we cannot separate normal dlls from Python extensions.
|
| 281 |
+
suffixes = []
|
| 282 |
+
suffixes += importlib.machinery.EXTENSION_SUFFIXES[:]
|
| 283 |
+
suffixes += importlib.machinery.SOURCE_SUFFIXES[:]
|
| 284 |
+
suffixes += importlib.machinery.BYTECODE_SUFFIXES[:]
|
| 285 |
+
for dir in m.__path__:
|
| 286 |
+
try:
|
| 287 |
+
names = os.listdir(dir)
|
| 288 |
+
except OSError:
|
| 289 |
+
self.msg(2, "can't list directory", dir)
|
| 290 |
+
continue
|
| 291 |
+
for name in names:
|
| 292 |
+
mod = None
|
| 293 |
+
for suff in suffixes:
|
| 294 |
+
n = len(suff)
|
| 295 |
+
if name[-n:] == suff:
|
| 296 |
+
mod = name[:-n]
|
| 297 |
+
break
|
| 298 |
+
if mod and mod != "__init__":
|
| 299 |
+
modules[mod] = mod
|
| 300 |
+
return modules.keys()
|
| 301 |
+
|
| 302 |
+
def import_module(self, partname, fqname, parent):
|
| 303 |
+
self.msgin(3, "import_module", partname, fqname, parent)
|
| 304 |
+
try:
|
| 305 |
+
m = self.modules[fqname]
|
| 306 |
+
except KeyError:
|
| 307 |
+
pass
|
| 308 |
+
else:
|
| 309 |
+
self.msgout(3, "import_module ->", m)
|
| 310 |
+
return m
|
| 311 |
+
if fqname in self.badmodules:
|
| 312 |
+
self.msgout(3, "import_module -> None")
|
| 313 |
+
return None
|
| 314 |
+
if parent and parent.__path__ is None:
|
| 315 |
+
self.msgout(3, "import_module -> None")
|
| 316 |
+
return None
|
| 317 |
+
try:
|
| 318 |
+
fp, pathname, stuff = self.find_module(partname,
|
| 319 |
+
parent and parent.__path__, parent)
|
| 320 |
+
except ImportError:
|
| 321 |
+
self.msgout(3, "import_module ->", None)
|
| 322 |
+
return None
|
| 323 |
+
|
| 324 |
+
try:
|
| 325 |
+
m = self.load_module(fqname, fp, pathname, stuff)
|
| 326 |
+
finally:
|
| 327 |
+
if fp:
|
| 328 |
+
fp.close()
|
| 329 |
+
if parent:
|
| 330 |
+
setattr(parent, partname, m)
|
| 331 |
+
self.msgout(3, "import_module ->", m)
|
| 332 |
+
return m
|
| 333 |
+
|
| 334 |
+
def load_module(self, fqname, fp, pathname, file_info):
|
| 335 |
+
suffix, mode, type = file_info
|
| 336 |
+
self.msgin(2, "load_module", fqname, fp and "fp", pathname)
|
| 337 |
+
if type == _PKG_DIRECTORY:
|
| 338 |
+
m = self.load_package(fqname, pathname)
|
| 339 |
+
self.msgout(2, "load_module ->", m)
|
| 340 |
+
return m
|
| 341 |
+
if type == _PY_SOURCE:
|
| 342 |
+
co = compile(fp.read(), pathname, 'exec')
|
| 343 |
+
elif type == _PY_COMPILED:
|
| 344 |
+
try:
|
| 345 |
+
data = fp.read()
|
| 346 |
+
importlib._bootstrap_external._classify_pyc(data, fqname, {})
|
| 347 |
+
except ImportError as exc:
|
| 348 |
+
self.msgout(2, "raise ImportError: " + str(exc), pathname)
|
| 349 |
+
raise
|
| 350 |
+
co = marshal.loads(memoryview(data)[16:])
|
| 351 |
+
else:
|
| 352 |
+
co = None
|
| 353 |
+
m = self.add_module(fqname)
|
| 354 |
+
m.__file__ = pathname
|
| 355 |
+
if co:
|
| 356 |
+
if self.replace_paths:
|
| 357 |
+
co = self.replace_paths_in_code(co)
|
| 358 |
+
m.__code__ = co
|
| 359 |
+
self.scan_code(co, m)
|
| 360 |
+
self.msgout(2, "load_module ->", m)
|
| 361 |
+
return m
|
| 362 |
+
|
| 363 |
+
def _add_badmodule(self, name, caller):
|
| 364 |
+
if name not in self.badmodules:
|
| 365 |
+
self.badmodules[name] = {}
|
| 366 |
+
if caller:
|
| 367 |
+
self.badmodules[name][caller.__name__] = 1
|
| 368 |
+
else:
|
| 369 |
+
self.badmodules[name]["-"] = 1
|
| 370 |
+
|
| 371 |
+
def _safe_import_hook(self, name, caller, fromlist, level=-1):
|
| 372 |
+
# wrapper for self.import_hook() that won't raise ImportError
|
| 373 |
+
if name in self.badmodules:
|
| 374 |
+
self._add_badmodule(name, caller)
|
| 375 |
+
return
|
| 376 |
+
try:
|
| 377 |
+
self.import_hook(name, caller, level=level)
|
| 378 |
+
except ImportError as msg:
|
| 379 |
+
self.msg(2, "ImportError:", str(msg))
|
| 380 |
+
self._add_badmodule(name, caller)
|
| 381 |
+
except SyntaxError as msg:
|
| 382 |
+
self.msg(2, "SyntaxError:", str(msg))
|
| 383 |
+
self._add_badmodule(name, caller)
|
| 384 |
+
else:
|
| 385 |
+
if fromlist:
|
| 386 |
+
for sub in fromlist:
|
| 387 |
+
fullname = name + "." + sub
|
| 388 |
+
if fullname in self.badmodules:
|
| 389 |
+
self._add_badmodule(fullname, caller)
|
| 390 |
+
continue
|
| 391 |
+
try:
|
| 392 |
+
self.import_hook(name, caller, [sub], level=level)
|
| 393 |
+
except ImportError as msg:
|
| 394 |
+
self.msg(2, "ImportError:", str(msg))
|
| 395 |
+
self._add_badmodule(fullname, caller)
|
| 396 |
+
|
| 397 |
+
def scan_opcodes(self, co):
|
| 398 |
+
# Scan the code, and yield 'interesting' opcode combinations
|
| 399 |
+
code = co.co_code
|
| 400 |
+
names = co.co_names
|
| 401 |
+
consts = co.co_consts
|
| 402 |
+
opargs = [(op, arg) for _, op, arg in dis._unpack_opargs(code)
|
| 403 |
+
if op != EXTENDED_ARG]
|
| 404 |
+
for i, (op, oparg) in enumerate(opargs):
|
| 405 |
+
if op in STORE_OPS:
|
| 406 |
+
yield "store", (names[oparg],)
|
| 407 |
+
continue
|
| 408 |
+
if (op == IMPORT_NAME and i >= 2
|
| 409 |
+
and opargs[i-1][0] == opargs[i-2][0] == LOAD_CONST):
|
| 410 |
+
level = consts[opargs[i-2][1]]
|
| 411 |
+
fromlist = consts[opargs[i-1][1]]
|
| 412 |
+
if level == 0: # absolute import
|
| 413 |
+
yield "absolute_import", (fromlist, names[oparg])
|
| 414 |
+
else: # relative import
|
| 415 |
+
yield "relative_import", (level, fromlist, names[oparg])
|
| 416 |
+
continue
|
| 417 |
+
|
| 418 |
+
def scan_code(self, co, m):
|
| 419 |
+
code = co.co_code
|
| 420 |
+
scanner = self.scan_opcodes
|
| 421 |
+
for what, args in scanner(co):
|
| 422 |
+
if what == "store":
|
| 423 |
+
name, = args
|
| 424 |
+
m.globalnames[name] = 1
|
| 425 |
+
elif what == "absolute_import":
|
| 426 |
+
fromlist, name = args
|
| 427 |
+
have_star = 0
|
| 428 |
+
if fromlist is not None:
|
| 429 |
+
if "*" in fromlist:
|
| 430 |
+
have_star = 1
|
| 431 |
+
fromlist = [f for f in fromlist if f != "*"]
|
| 432 |
+
self._safe_import_hook(name, m, fromlist, level=0)
|
| 433 |
+
if have_star:
|
| 434 |
+
# We've encountered an "import *". If it is a Python module,
|
| 435 |
+
# the code has already been parsed and we can suck out the
|
| 436 |
+
# global names.
|
| 437 |
+
mm = None
|
| 438 |
+
if m.__path__:
|
| 439 |
+
# At this point we don't know whether 'name' is a
|
| 440 |
+
# submodule of 'm' or a global module. Let's just try
|
| 441 |
+
# the full name first.
|
| 442 |
+
mm = self.modules.get(m.__name__ + "." + name)
|
| 443 |
+
if mm is None:
|
| 444 |
+
mm = self.modules.get(name)
|
| 445 |
+
if mm is not None:
|
| 446 |
+
m.globalnames.update(mm.globalnames)
|
| 447 |
+
m.starimports.update(mm.starimports)
|
| 448 |
+
if mm.__code__ is None:
|
| 449 |
+
m.starimports[name] = 1
|
| 450 |
+
else:
|
| 451 |
+
m.starimports[name] = 1
|
| 452 |
+
elif what == "relative_import":
|
| 453 |
+
level, fromlist, name = args
|
| 454 |
+
if name:
|
| 455 |
+
self._safe_import_hook(name, m, fromlist, level=level)
|
| 456 |
+
else:
|
| 457 |
+
parent = self.determine_parent(m, level=level)
|
| 458 |
+
self._safe_import_hook(parent.__name__, None, fromlist, level=0)
|
| 459 |
+
else:
|
| 460 |
+
# We don't expect anything else from the generator.
|
| 461 |
+
raise RuntimeError(what)
|
| 462 |
+
|
| 463 |
+
for c in co.co_consts:
|
| 464 |
+
if isinstance(c, type(co)):
|
| 465 |
+
self.scan_code(c, m)
|
| 466 |
+
|
| 467 |
+
def load_package(self, fqname, pathname):
|
| 468 |
+
self.msgin(2, "load_package", fqname, pathname)
|
| 469 |
+
newname = replacePackageMap.get(fqname)
|
| 470 |
+
if newname:
|
| 471 |
+
fqname = newname
|
| 472 |
+
m = self.add_module(fqname)
|
| 473 |
+
m.__file__ = pathname
|
| 474 |
+
m.__path__ = [pathname]
|
| 475 |
+
|
| 476 |
+
# As per comment at top of file, simulate runtime __path__ additions.
|
| 477 |
+
m.__path__ = m.__path__ + packagePathMap.get(fqname, [])
|
| 478 |
+
|
| 479 |
+
fp, buf, stuff = self.find_module("__init__", m.__path__)
|
| 480 |
+
try:
|
| 481 |
+
self.load_module(fqname, fp, buf, stuff)
|
| 482 |
+
self.msgout(2, "load_package ->", m)
|
| 483 |
+
return m
|
| 484 |
+
finally:
|
| 485 |
+
if fp:
|
| 486 |
+
fp.close()
|
| 487 |
+
|
| 488 |
+
def add_module(self, fqname):
|
| 489 |
+
if fqname in self.modules:
|
| 490 |
+
return self.modules[fqname]
|
| 491 |
+
self.modules[fqname] = m = Module(fqname)
|
| 492 |
+
return m
|
| 493 |
+
|
| 494 |
+
def find_module(self, name, path, parent=None):
|
| 495 |
+
if parent is not None:
|
| 496 |
+
# assert path is not None
|
| 497 |
+
fullname = parent.__name__+'.'+name
|
| 498 |
+
else:
|
| 499 |
+
fullname = name
|
| 500 |
+
if fullname in self.excludes:
|
| 501 |
+
self.msgout(3, "find_module -> Excluded", fullname)
|
| 502 |
+
raise ImportError(name)
|
| 503 |
+
|
| 504 |
+
if path is None:
|
| 505 |
+
if name in sys.builtin_module_names:
|
| 506 |
+
return (None, None, ("", "", _C_BUILTIN))
|
| 507 |
+
|
| 508 |
+
path = self.path
|
| 509 |
+
|
| 510 |
+
return _find_module(name, path)
|
| 511 |
+
|
| 512 |
+
def report(self):
|
| 513 |
+
"""Print a report to stdout, listing the found modules with their
|
| 514 |
+
paths, as well as modules that are missing, or seem to be missing.
|
| 515 |
+
"""
|
| 516 |
+
print()
|
| 517 |
+
print(" %-25s %s" % ("Name", "File"))
|
| 518 |
+
print(" %-25s %s" % ("----", "----"))
|
| 519 |
+
# Print modules found
|
| 520 |
+
keys = sorted(self.modules.keys())
|
| 521 |
+
for key in keys:
|
| 522 |
+
m = self.modules[key]
|
| 523 |
+
if m.__path__:
|
| 524 |
+
print("P", end=' ')
|
| 525 |
+
else:
|
| 526 |
+
print("m", end=' ')
|
| 527 |
+
print("%-25s" % key, m.__file__ or "")
|
| 528 |
+
|
| 529 |
+
# Print missing modules
|
| 530 |
+
missing, maybe = self.any_missing_maybe()
|
| 531 |
+
if missing:
|
| 532 |
+
print()
|
| 533 |
+
print("Missing modules:")
|
| 534 |
+
for name in missing:
|
| 535 |
+
mods = sorted(self.badmodules[name].keys())
|
| 536 |
+
print("?", name, "imported from", ', '.join(mods))
|
| 537 |
+
# Print modules that may be missing, but then again, maybe not...
|
| 538 |
+
if maybe:
|
| 539 |
+
print()
|
| 540 |
+
print("Submodules that appear to be missing, but could also be", end=' ')
|
| 541 |
+
print("global names in the parent package:")
|
| 542 |
+
for name in maybe:
|
| 543 |
+
mods = sorted(self.badmodules[name].keys())
|
| 544 |
+
print("?", name, "imported from", ', '.join(mods))
|
| 545 |
+
|
| 546 |
+
def any_missing(self):
|
| 547 |
+
"""Return a list of modules that appear to be missing. Use
|
| 548 |
+
any_missing_maybe() if you want to know which modules are
|
| 549 |
+
certain to be missing, and which *may* be missing.
|
| 550 |
+
"""
|
| 551 |
+
missing, maybe = self.any_missing_maybe()
|
| 552 |
+
return missing + maybe
|
| 553 |
+
|
| 554 |
+
def any_missing_maybe(self):
|
| 555 |
+
"""Return two lists, one with modules that are certainly missing
|
| 556 |
+
and one with modules that *may* be missing. The latter names could
|
| 557 |
+
either be submodules *or* just global names in the package.
|
| 558 |
+
|
| 559 |
+
The reason it can't always be determined is that it's impossible to
|
| 560 |
+
tell which names are imported when "from module import *" is done
|
| 561 |
+
with an extension module, short of actually importing it.
|
| 562 |
+
"""
|
| 563 |
+
missing = []
|
| 564 |
+
maybe = []
|
| 565 |
+
for name in self.badmodules:
|
| 566 |
+
if name in self.excludes:
|
| 567 |
+
continue
|
| 568 |
+
i = name.rfind(".")
|
| 569 |
+
if i < 0:
|
| 570 |
+
missing.append(name)
|
| 571 |
+
continue
|
| 572 |
+
subname = name[i+1:]
|
| 573 |
+
pkgname = name[:i]
|
| 574 |
+
pkg = self.modules.get(pkgname)
|
| 575 |
+
if pkg is not None:
|
| 576 |
+
if pkgname in self.badmodules[name]:
|
| 577 |
+
# The package tried to import this module itself and
|
| 578 |
+
# failed. It's definitely missing.
|
| 579 |
+
missing.append(name)
|
| 580 |
+
elif subname in pkg.globalnames:
|
| 581 |
+
# It's a global in the package: definitely not missing.
|
| 582 |
+
pass
|
| 583 |
+
elif pkg.starimports:
|
| 584 |
+
# It could be missing, but the package did an "import *"
|
| 585 |
+
# from a non-Python module, so we simply can't be sure.
|
| 586 |
+
maybe.append(name)
|
| 587 |
+
else:
|
| 588 |
+
# It's not a global in the package, the package didn't
|
| 589 |
+
# do funny star imports, it's very likely to be missing.
|
| 590 |
+
# The symbol could be inserted into the package from the
|
| 591 |
+
# outside, but since that's not good style we simply list
|
| 592 |
+
# it missing.
|
| 593 |
+
missing.append(name)
|
| 594 |
+
else:
|
| 595 |
+
missing.append(name)
|
| 596 |
+
missing.sort()
|
| 597 |
+
maybe.sort()
|
| 598 |
+
return missing, maybe
|
| 599 |
+
|
| 600 |
+
def replace_paths_in_code(self, co):
|
| 601 |
+
new_filename = original_filename = os.path.normpath(co.co_filename)
|
| 602 |
+
for f, r in self.replace_paths:
|
| 603 |
+
if original_filename.startswith(f):
|
| 604 |
+
new_filename = r + original_filename[len(f):]
|
| 605 |
+
break
|
| 606 |
+
|
| 607 |
+
if self.debug and original_filename not in self.processed_paths:
|
| 608 |
+
if new_filename != original_filename:
|
| 609 |
+
self.msgout(2, "co_filename %r changed to %r" \
|
| 610 |
+
% (original_filename,new_filename,))
|
| 611 |
+
else:
|
| 612 |
+
self.msgout(2, "co_filename %r remains unchanged" \
|
| 613 |
+
% (original_filename,))
|
| 614 |
+
self.processed_paths.append(original_filename)
|
| 615 |
+
|
| 616 |
+
consts = list(co.co_consts)
|
| 617 |
+
for i in range(len(consts)):
|
| 618 |
+
if isinstance(consts[i], type(co)):
|
| 619 |
+
consts[i] = self.replace_paths_in_code(consts[i])
|
| 620 |
+
|
| 621 |
+
return co.replace(co_consts=tuple(consts), co_filename=new_filename)
|
| 622 |
+
|
| 623 |
+
|
| 624 |
+
def test():
|
| 625 |
+
# Parse command line
|
| 626 |
+
import getopt
|
| 627 |
+
try:
|
| 628 |
+
opts, args = getopt.getopt(sys.argv[1:], "dmp:qx:")
|
| 629 |
+
except getopt.error as msg:
|
| 630 |
+
print(msg)
|
| 631 |
+
return
|
| 632 |
+
|
| 633 |
+
# Process options
|
| 634 |
+
debug = 1
|
| 635 |
+
domods = 0
|
| 636 |
+
addpath = []
|
| 637 |
+
exclude = []
|
| 638 |
+
for o, a in opts:
|
| 639 |
+
if o == '-d':
|
| 640 |
+
debug = debug + 1
|
| 641 |
+
if o == '-m':
|
| 642 |
+
domods = 1
|
| 643 |
+
if o == '-p':
|
| 644 |
+
addpath = addpath + a.split(os.pathsep)
|
| 645 |
+
if o == '-q':
|
| 646 |
+
debug = 0
|
| 647 |
+
if o == '-x':
|
| 648 |
+
exclude.append(a)
|
| 649 |
+
|
| 650 |
+
# Provide default arguments
|
| 651 |
+
if not args:
|
| 652 |
+
script = "hello.py"
|
| 653 |
+
else:
|
| 654 |
+
script = args[0]
|
| 655 |
+
|
| 656 |
+
# Set the path based on sys.path and the script directory
|
| 657 |
+
path = sys.path[:]
|
| 658 |
+
path[0] = os.path.dirname(script)
|
| 659 |
+
path = addpath + path
|
| 660 |
+
if debug > 1:
|
| 661 |
+
print("path:")
|
| 662 |
+
for item in path:
|
| 663 |
+
print(" ", repr(item))
|
| 664 |
+
|
| 665 |
+
# Create the module finder and turn its crank
|
| 666 |
+
mf = ModuleFinder(path, debug, exclude)
|
| 667 |
+
for arg in args[1:]:
|
| 668 |
+
if arg == '-m':
|
| 669 |
+
domods = 1
|
| 670 |
+
continue
|
| 671 |
+
if domods:
|
| 672 |
+
if arg[-2:] == '.*':
|
| 673 |
+
mf.import_hook(arg[:-2], None, ["*"])
|
| 674 |
+
else:
|
| 675 |
+
mf.import_hook(arg)
|
| 676 |
+
else:
|
| 677 |
+
mf.load_file(arg)
|
| 678 |
+
mf.run_script(script)
|
| 679 |
+
mf.report()
|
| 680 |
+
return mf # for -i debugging
|
| 681 |
+
|
| 682 |
+
|
| 683 |
+
if __name__ == '__main__':
|
| 684 |
+
try:
|
| 685 |
+
mf = test()
|
| 686 |
+
except KeyboardInterrupt:
|
| 687 |
+
print("\n[interrupted]")
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/netrc.py
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""An object-oriented interface to .netrc files."""
|
| 2 |
+
|
| 3 |
+
# Module and documentation by Eric S. Raymond, 21 Dec 1998
|
| 4 |
+
|
| 5 |
+
import os, shlex, stat
|
| 6 |
+
|
| 7 |
+
__all__ = ["netrc", "NetrcParseError"]
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
class NetrcParseError(Exception):
|
| 11 |
+
"""Exception raised on syntax errors in the .netrc file."""
|
| 12 |
+
def __init__(self, msg, filename=None, lineno=None):
|
| 13 |
+
self.filename = filename
|
| 14 |
+
self.lineno = lineno
|
| 15 |
+
self.msg = msg
|
| 16 |
+
Exception.__init__(self, msg)
|
| 17 |
+
|
| 18 |
+
def __str__(self):
|
| 19 |
+
return "%s (%s, line %s)" % (self.msg, self.filename, self.lineno)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
class netrc:
|
| 23 |
+
def __init__(self, file=None):
|
| 24 |
+
default_netrc = file is None
|
| 25 |
+
if file is None:
|
| 26 |
+
file = os.path.join(os.path.expanduser("~"), ".netrc")
|
| 27 |
+
self.hosts = {}
|
| 28 |
+
self.macros = {}
|
| 29 |
+
with open(file) as fp:
|
| 30 |
+
self._parse(file, fp, default_netrc)
|
| 31 |
+
|
| 32 |
+
def _parse(self, file, fp, default_netrc):
|
| 33 |
+
lexer = shlex.shlex(fp)
|
| 34 |
+
lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""
|
| 35 |
+
lexer.commenters = lexer.commenters.replace('#', '')
|
| 36 |
+
while 1:
|
| 37 |
+
# Look for a machine, default, or macdef top-level keyword
|
| 38 |
+
saved_lineno = lexer.lineno
|
| 39 |
+
toplevel = tt = lexer.get_token()
|
| 40 |
+
if not tt:
|
| 41 |
+
break
|
| 42 |
+
elif tt[0] == '#':
|
| 43 |
+
if lexer.lineno == saved_lineno and len(tt) == 1:
|
| 44 |
+
lexer.instream.readline()
|
| 45 |
+
continue
|
| 46 |
+
elif tt == 'machine':
|
| 47 |
+
entryname = lexer.get_token()
|
| 48 |
+
elif tt == 'default':
|
| 49 |
+
entryname = 'default'
|
| 50 |
+
elif tt == 'macdef': # Just skip to end of macdefs
|
| 51 |
+
entryname = lexer.get_token()
|
| 52 |
+
self.macros[entryname] = []
|
| 53 |
+
lexer.whitespace = ' \t'
|
| 54 |
+
while 1:
|
| 55 |
+
line = lexer.instream.readline()
|
| 56 |
+
if not line or line == '\012':
|
| 57 |
+
lexer.whitespace = ' \t\r\n'
|
| 58 |
+
break
|
| 59 |
+
self.macros[entryname].append(line)
|
| 60 |
+
continue
|
| 61 |
+
else:
|
| 62 |
+
raise NetrcParseError(
|
| 63 |
+
"bad toplevel token %r" % tt, file, lexer.lineno)
|
| 64 |
+
|
| 65 |
+
# We're looking at start of an entry for a named machine or default.
|
| 66 |
+
login = ''
|
| 67 |
+
account = password = None
|
| 68 |
+
self.hosts[entryname] = {}
|
| 69 |
+
while 1:
|
| 70 |
+
tt = lexer.get_token()
|
| 71 |
+
if (tt.startswith('#') or
|
| 72 |
+
tt in {'', 'machine', 'default', 'macdef'}):
|
| 73 |
+
if password:
|
| 74 |
+
self.hosts[entryname] = (login, account, password)
|
| 75 |
+
lexer.push_token(tt)
|
| 76 |
+
break
|
| 77 |
+
else:
|
| 78 |
+
raise NetrcParseError(
|
| 79 |
+
"malformed %s entry %s terminated by %s"
|
| 80 |
+
% (toplevel, entryname, repr(tt)),
|
| 81 |
+
file, lexer.lineno)
|
| 82 |
+
elif tt == 'login' or tt == 'user':
|
| 83 |
+
login = lexer.get_token()
|
| 84 |
+
elif tt == 'account':
|
| 85 |
+
account = lexer.get_token()
|
| 86 |
+
elif tt == 'password':
|
| 87 |
+
if os.name == 'posix' and default_netrc:
|
| 88 |
+
prop = os.fstat(fp.fileno())
|
| 89 |
+
if prop.st_uid != os.getuid():
|
| 90 |
+
import pwd
|
| 91 |
+
try:
|
| 92 |
+
fowner = pwd.getpwuid(prop.st_uid)[0]
|
| 93 |
+
except KeyError:
|
| 94 |
+
fowner = 'uid %s' % prop.st_uid
|
| 95 |
+
try:
|
| 96 |
+
user = pwd.getpwuid(os.getuid())[0]
|
| 97 |
+
except KeyError:
|
| 98 |
+
user = 'uid %s' % os.getuid()
|
| 99 |
+
raise NetrcParseError(
|
| 100 |
+
("~/.netrc file owner (%s) does not match"
|
| 101 |
+
" current user (%s)") % (fowner, user),
|
| 102 |
+
file, lexer.lineno)
|
| 103 |
+
if (prop.st_mode & (stat.S_IRWXG | stat.S_IRWXO)):
|
| 104 |
+
raise NetrcParseError(
|
| 105 |
+
"~/.netrc access too permissive: access"
|
| 106 |
+
" permissions must restrict access to only"
|
| 107 |
+
" the owner", file, lexer.lineno)
|
| 108 |
+
password = lexer.get_token()
|
| 109 |
+
else:
|
| 110 |
+
raise NetrcParseError("bad follower token %r" % tt,
|
| 111 |
+
file, lexer.lineno)
|
| 112 |
+
|
| 113 |
+
def authenticators(self, host):
|
| 114 |
+
"""Return a (user, account, password) tuple for given host."""
|
| 115 |
+
if host in self.hosts:
|
| 116 |
+
return self.hosts[host]
|
| 117 |
+
elif 'default' in self.hosts:
|
| 118 |
+
return self.hosts['default']
|
| 119 |
+
else:
|
| 120 |
+
return None
|
| 121 |
+
|
| 122 |
+
def __repr__(self):
|
| 123 |
+
"""Dump the class data in the format of a .netrc file."""
|
| 124 |
+
rep = ""
|
| 125 |
+
for host in self.hosts.keys():
|
| 126 |
+
attrs = self.hosts[host]
|
| 127 |
+
rep += f"machine {host}\n\tlogin {attrs[0]}\n"
|
| 128 |
+
if attrs[1]:
|
| 129 |
+
rep += f"\taccount {attrs[1]}\n"
|
| 130 |
+
rep += f"\tpassword {attrs[2]}\n"
|
| 131 |
+
for macro in self.macros.keys():
|
| 132 |
+
rep += f"macdef {macro}\n"
|
| 133 |
+
for line in self.macros[macro]:
|
| 134 |
+
rep += line
|
| 135 |
+
rep += "\n"
|
| 136 |
+
return rep
|
| 137 |
+
|
| 138 |
+
if __name__ == '__main__':
|
| 139 |
+
print(netrc())
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/nntplib.py
ADDED
|
@@ -0,0 +1,1151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""An NNTP client class based on:
|
| 2 |
+
- RFC 977: Network News Transfer Protocol
|
| 3 |
+
- RFC 2980: Common NNTP Extensions
|
| 4 |
+
- RFC 3977: Network News Transfer Protocol (version 2)
|
| 5 |
+
|
| 6 |
+
Example:
|
| 7 |
+
|
| 8 |
+
>>> from nntplib import NNTP
|
| 9 |
+
>>> s = NNTP('news')
|
| 10 |
+
>>> resp, count, first, last, name = s.group('comp.lang.python')
|
| 11 |
+
>>> print('Group', name, 'has', count, 'articles, range', first, 'to', last)
|
| 12 |
+
Group comp.lang.python has 51 articles, range 5770 to 5821
|
| 13 |
+
>>> resp, subs = s.xhdr('subject', '{0}-{1}'.format(first, last))
|
| 14 |
+
>>> resp = s.quit()
|
| 15 |
+
>>>
|
| 16 |
+
|
| 17 |
+
Here 'resp' is the server response line.
|
| 18 |
+
Error responses are turned into exceptions.
|
| 19 |
+
|
| 20 |
+
To post an article from a file:
|
| 21 |
+
>>> f = open(filename, 'rb') # file containing article, including header
|
| 22 |
+
>>> resp = s.post(f)
|
| 23 |
+
>>>
|
| 24 |
+
|
| 25 |
+
For descriptions of all methods, read the comments in the code below.
|
| 26 |
+
Note that all arguments and return values representing article numbers
|
| 27 |
+
are strings, not numbers, since they are rarely used for calculations.
|
| 28 |
+
"""
|
| 29 |
+
|
| 30 |
+
# RFC 977 by Brian Kantor and Phil Lapsley.
|
| 31 |
+
# xover, xgtitle, xpath, date methods by Kevan Heydon
|
| 32 |
+
|
| 33 |
+
# Incompatible changes from the 2.x nntplib:
|
| 34 |
+
# - all commands are encoded as UTF-8 data (using the "surrogateescape"
|
| 35 |
+
# error handler), except for raw message data (POST, IHAVE)
|
| 36 |
+
# - all responses are decoded as UTF-8 data (using the "surrogateescape"
|
| 37 |
+
# error handler), except for raw message data (ARTICLE, HEAD, BODY)
|
| 38 |
+
# - the `file` argument to various methods is keyword-only
|
| 39 |
+
#
|
| 40 |
+
# - NNTP.date() returns a datetime object
|
| 41 |
+
# - NNTP.newgroups() and NNTP.newnews() take a datetime (or date) object,
|
| 42 |
+
# rather than a pair of (date, time) strings.
|
| 43 |
+
# - NNTP.newgroups() and NNTP.list() return a list of GroupInfo named tuples
|
| 44 |
+
# - NNTP.descriptions() returns a dict mapping group names to descriptions
|
| 45 |
+
# - NNTP.xover() returns a list of dicts mapping field names (header or metadata)
|
| 46 |
+
# to field values; each dict representing a message overview.
|
| 47 |
+
# - NNTP.article(), NNTP.head() and NNTP.body() return a (response, ArticleInfo)
|
| 48 |
+
# tuple.
|
| 49 |
+
# - the "internal" methods have been marked private (they now start with
|
| 50 |
+
# an underscore)
|
| 51 |
+
|
| 52 |
+
# Other changes from the 2.x/3.1 nntplib:
|
| 53 |
+
# - automatic querying of capabilities at connect
|
| 54 |
+
# - New method NNTP.getcapabilities()
|
| 55 |
+
# - New method NNTP.over()
|
| 56 |
+
# - New helper function decode_header()
|
| 57 |
+
# - NNTP.post() and NNTP.ihave() accept file objects, bytes-like objects and
|
| 58 |
+
# arbitrary iterables yielding lines.
|
| 59 |
+
# - An extensive test suite :-)
|
| 60 |
+
|
| 61 |
+
# TODO:
|
| 62 |
+
# - return structured data (GroupInfo etc.) everywhere
|
| 63 |
+
# - support HDR
|
| 64 |
+
|
| 65 |
+
# Imports
|
| 66 |
+
import re
|
| 67 |
+
import socket
|
| 68 |
+
import collections
|
| 69 |
+
import datetime
|
| 70 |
+
import warnings
|
| 71 |
+
import sys
|
| 72 |
+
|
| 73 |
+
try:
|
| 74 |
+
import ssl
|
| 75 |
+
except ImportError:
|
| 76 |
+
_have_ssl = False
|
| 77 |
+
else:
|
| 78 |
+
_have_ssl = True
|
| 79 |
+
|
| 80 |
+
from email.header import decode_header as _email_decode_header
|
| 81 |
+
from socket import _GLOBAL_DEFAULT_TIMEOUT
|
| 82 |
+
|
| 83 |
+
__all__ = ["NNTP",
|
| 84 |
+
"NNTPError", "NNTPReplyError", "NNTPTemporaryError",
|
| 85 |
+
"NNTPPermanentError", "NNTPProtocolError", "NNTPDataError",
|
| 86 |
+
"decode_header",
|
| 87 |
+
]
|
| 88 |
+
|
| 89 |
+
# maximal line length when calling readline(). This is to prevent
|
| 90 |
+
# reading arbitrary length lines. RFC 3977 limits NNTP line length to
|
| 91 |
+
# 512 characters, including CRLF. We have selected 2048 just to be on
|
| 92 |
+
# the safe side.
|
| 93 |
+
_MAXLINE = 2048
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
# Exceptions raised when an error or invalid response is received
|
| 97 |
+
class NNTPError(Exception):
|
| 98 |
+
"""Base class for all nntplib exceptions"""
|
| 99 |
+
def __init__(self, *args):
|
| 100 |
+
Exception.__init__(self, *args)
|
| 101 |
+
try:
|
| 102 |
+
self.response = args[0]
|
| 103 |
+
except IndexError:
|
| 104 |
+
self.response = 'No response given'
|
| 105 |
+
|
| 106 |
+
class NNTPReplyError(NNTPError):
|
| 107 |
+
"""Unexpected [123]xx reply"""
|
| 108 |
+
pass
|
| 109 |
+
|
| 110 |
+
class NNTPTemporaryError(NNTPError):
|
| 111 |
+
"""4xx errors"""
|
| 112 |
+
pass
|
| 113 |
+
|
| 114 |
+
class NNTPPermanentError(NNTPError):
|
| 115 |
+
"""5xx errors"""
|
| 116 |
+
pass
|
| 117 |
+
|
| 118 |
+
class NNTPProtocolError(NNTPError):
|
| 119 |
+
"""Response does not begin with [1-5]"""
|
| 120 |
+
pass
|
| 121 |
+
|
| 122 |
+
class NNTPDataError(NNTPError):
|
| 123 |
+
"""Error in response data"""
|
| 124 |
+
pass
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
# Standard port used by NNTP servers
|
| 128 |
+
NNTP_PORT = 119
|
| 129 |
+
NNTP_SSL_PORT = 563
|
| 130 |
+
|
| 131 |
+
# Response numbers that are followed by additional text (e.g. article)
|
| 132 |
+
_LONGRESP = {
|
| 133 |
+
'100', # HELP
|
| 134 |
+
'101', # CAPABILITIES
|
| 135 |
+
'211', # LISTGROUP (also not multi-line with GROUP)
|
| 136 |
+
'215', # LIST
|
| 137 |
+
'220', # ARTICLE
|
| 138 |
+
'221', # HEAD, XHDR
|
| 139 |
+
'222', # BODY
|
| 140 |
+
'224', # OVER, XOVER
|
| 141 |
+
'225', # HDR
|
| 142 |
+
'230', # NEWNEWS
|
| 143 |
+
'231', # NEWGROUPS
|
| 144 |
+
'282', # XGTITLE
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
# Default decoded value for LIST OVERVIEW.FMT if not supported
|
| 148 |
+
_DEFAULT_OVERVIEW_FMT = [
|
| 149 |
+
"subject", "from", "date", "message-id", "references", ":bytes", ":lines"]
|
| 150 |
+
|
| 151 |
+
# Alternative names allowed in LIST OVERVIEW.FMT response
|
| 152 |
+
_OVERVIEW_FMT_ALTERNATIVES = {
|
| 153 |
+
'bytes': ':bytes',
|
| 154 |
+
'lines': ':lines',
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
# Line terminators (we always output CRLF, but accept any of CRLF, CR, LF)
|
| 158 |
+
_CRLF = b'\r\n'
|
| 159 |
+
|
| 160 |
+
GroupInfo = collections.namedtuple('GroupInfo',
|
| 161 |
+
['group', 'last', 'first', 'flag'])
|
| 162 |
+
|
| 163 |
+
ArticleInfo = collections.namedtuple('ArticleInfo',
|
| 164 |
+
['number', 'message_id', 'lines'])
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
# Helper function(s)
|
| 168 |
+
def decode_header(header_str):
|
| 169 |
+
"""Takes a unicode string representing a munged header value
|
| 170 |
+
and decodes it as a (possibly non-ASCII) readable value."""
|
| 171 |
+
parts = []
|
| 172 |
+
for v, enc in _email_decode_header(header_str):
|
| 173 |
+
if isinstance(v, bytes):
|
| 174 |
+
parts.append(v.decode(enc or 'ascii'))
|
| 175 |
+
else:
|
| 176 |
+
parts.append(v)
|
| 177 |
+
return ''.join(parts)
|
| 178 |
+
|
| 179 |
+
def _parse_overview_fmt(lines):
|
| 180 |
+
"""Parse a list of string representing the response to LIST OVERVIEW.FMT
|
| 181 |
+
and return a list of header/metadata names.
|
| 182 |
+
Raises NNTPDataError if the response is not compliant
|
| 183 |
+
(cf. RFC 3977, section 8.4)."""
|
| 184 |
+
fmt = []
|
| 185 |
+
for line in lines:
|
| 186 |
+
if line[0] == ':':
|
| 187 |
+
# Metadata name (e.g. ":bytes")
|
| 188 |
+
name, _, suffix = line[1:].partition(':')
|
| 189 |
+
name = ':' + name
|
| 190 |
+
else:
|
| 191 |
+
# Header name (e.g. "Subject:" or "Xref:full")
|
| 192 |
+
name, _, suffix = line.partition(':')
|
| 193 |
+
name = name.lower()
|
| 194 |
+
name = _OVERVIEW_FMT_ALTERNATIVES.get(name, name)
|
| 195 |
+
# Should we do something with the suffix?
|
| 196 |
+
fmt.append(name)
|
| 197 |
+
defaults = _DEFAULT_OVERVIEW_FMT
|
| 198 |
+
if len(fmt) < len(defaults):
|
| 199 |
+
raise NNTPDataError("LIST OVERVIEW.FMT response too short")
|
| 200 |
+
if fmt[:len(defaults)] != defaults:
|
| 201 |
+
raise NNTPDataError("LIST OVERVIEW.FMT redefines default fields")
|
| 202 |
+
return fmt
|
| 203 |
+
|
| 204 |
+
def _parse_overview(lines, fmt, data_process_func=None):
|
| 205 |
+
"""Parse the response to an OVER or XOVER command according to the
|
| 206 |
+
overview format `fmt`."""
|
| 207 |
+
n_defaults = len(_DEFAULT_OVERVIEW_FMT)
|
| 208 |
+
overview = []
|
| 209 |
+
for line in lines:
|
| 210 |
+
fields = {}
|
| 211 |
+
article_number, *tokens = line.split('\t')
|
| 212 |
+
article_number = int(article_number)
|
| 213 |
+
for i, token in enumerate(tokens):
|
| 214 |
+
if i >= len(fmt):
|
| 215 |
+
# XXX should we raise an error? Some servers might not
|
| 216 |
+
# support LIST OVERVIEW.FMT and still return additional
|
| 217 |
+
# headers.
|
| 218 |
+
continue
|
| 219 |
+
field_name = fmt[i]
|
| 220 |
+
is_metadata = field_name.startswith(':')
|
| 221 |
+
if i >= n_defaults and not is_metadata:
|
| 222 |
+
# Non-default header names are included in full in the response
|
| 223 |
+
# (unless the field is totally empty)
|
| 224 |
+
h = field_name + ": "
|
| 225 |
+
if token and token[:len(h)].lower() != h:
|
| 226 |
+
raise NNTPDataError("OVER/XOVER response doesn't include "
|
| 227 |
+
"names of additional headers")
|
| 228 |
+
token = token[len(h):] if token else None
|
| 229 |
+
fields[fmt[i]] = token
|
| 230 |
+
overview.append((article_number, fields))
|
| 231 |
+
return overview
|
| 232 |
+
|
| 233 |
+
def _parse_datetime(date_str, time_str=None):
|
| 234 |
+
"""Parse a pair of (date, time) strings, and return a datetime object.
|
| 235 |
+
If only the date is given, it is assumed to be date and time
|
| 236 |
+
concatenated together (e.g. response to the DATE command).
|
| 237 |
+
"""
|
| 238 |
+
if time_str is None:
|
| 239 |
+
time_str = date_str[-6:]
|
| 240 |
+
date_str = date_str[:-6]
|
| 241 |
+
hours = int(time_str[:2])
|
| 242 |
+
minutes = int(time_str[2:4])
|
| 243 |
+
seconds = int(time_str[4:])
|
| 244 |
+
year = int(date_str[:-4])
|
| 245 |
+
month = int(date_str[-4:-2])
|
| 246 |
+
day = int(date_str[-2:])
|
| 247 |
+
# RFC 3977 doesn't say how to interpret 2-char years. Assume that
|
| 248 |
+
# there are no dates before 1970 on Usenet.
|
| 249 |
+
if year < 70:
|
| 250 |
+
year += 2000
|
| 251 |
+
elif year < 100:
|
| 252 |
+
year += 1900
|
| 253 |
+
return datetime.datetime(year, month, day, hours, minutes, seconds)
|
| 254 |
+
|
| 255 |
+
def _unparse_datetime(dt, legacy=False):
|
| 256 |
+
"""Format a date or datetime object as a pair of (date, time) strings
|
| 257 |
+
in the format required by the NEWNEWS and NEWGROUPS commands. If a
|
| 258 |
+
date object is passed, the time is assumed to be midnight (00h00).
|
| 259 |
+
|
| 260 |
+
The returned representation depends on the legacy flag:
|
| 261 |
+
* if legacy is False (the default):
|
| 262 |
+
date has the YYYYMMDD format and time the HHMMSS format
|
| 263 |
+
* if legacy is True:
|
| 264 |
+
date has the YYMMDD format and time the HHMMSS format.
|
| 265 |
+
RFC 3977 compliant servers should understand both formats; therefore,
|
| 266 |
+
legacy is only needed when talking to old servers.
|
| 267 |
+
"""
|
| 268 |
+
if not isinstance(dt, datetime.datetime):
|
| 269 |
+
time_str = "000000"
|
| 270 |
+
else:
|
| 271 |
+
time_str = "{0.hour:02d}{0.minute:02d}{0.second:02d}".format(dt)
|
| 272 |
+
y = dt.year
|
| 273 |
+
if legacy:
|
| 274 |
+
y = y % 100
|
| 275 |
+
date_str = "{0:02d}{1.month:02d}{1.day:02d}".format(y, dt)
|
| 276 |
+
else:
|
| 277 |
+
date_str = "{0:04d}{1.month:02d}{1.day:02d}".format(y, dt)
|
| 278 |
+
return date_str, time_str
|
| 279 |
+
|
| 280 |
+
|
| 281 |
+
if _have_ssl:
|
| 282 |
+
|
| 283 |
+
def _encrypt_on(sock, context, hostname):
|
| 284 |
+
"""Wrap a socket in SSL/TLS. Arguments:
|
| 285 |
+
- sock: Socket to wrap
|
| 286 |
+
- context: SSL context to use for the encrypted connection
|
| 287 |
+
Returns:
|
| 288 |
+
- sock: New, encrypted socket.
|
| 289 |
+
"""
|
| 290 |
+
# Generate a default SSL context if none was passed.
|
| 291 |
+
if context is None:
|
| 292 |
+
context = ssl._create_stdlib_context()
|
| 293 |
+
return context.wrap_socket(sock, server_hostname=hostname)
|
| 294 |
+
|
| 295 |
+
|
| 296 |
+
# The classes themselves
|
| 297 |
+
class _NNTPBase:
|
| 298 |
+
# UTF-8 is the character set for all NNTP commands and responses: they
|
| 299 |
+
# are automatically encoded (when sending) and decoded (and receiving)
|
| 300 |
+
# by this class.
|
| 301 |
+
# However, some multi-line data blocks can contain arbitrary bytes (for
|
| 302 |
+
# example, latin-1 or utf-16 data in the body of a message). Commands
|
| 303 |
+
# taking (POST, IHAVE) or returning (HEAD, BODY, ARTICLE) raw message
|
| 304 |
+
# data will therefore only accept and produce bytes objects.
|
| 305 |
+
# Furthermore, since there could be non-compliant servers out there,
|
| 306 |
+
# we use 'surrogateescape' as the error handler for fault tolerance
|
| 307 |
+
# and easy round-tripping. This could be useful for some applications
|
| 308 |
+
# (e.g. NNTP gateways).
|
| 309 |
+
|
| 310 |
+
encoding = 'utf-8'
|
| 311 |
+
errors = 'surrogateescape'
|
| 312 |
+
|
| 313 |
+
def __init__(self, file, host,
|
| 314 |
+
readermode=None, timeout=_GLOBAL_DEFAULT_TIMEOUT):
|
| 315 |
+
"""Initialize an instance. Arguments:
|
| 316 |
+
- file: file-like object (open for read/write in binary mode)
|
| 317 |
+
- host: hostname of the server
|
| 318 |
+
- readermode: if true, send 'mode reader' command after
|
| 319 |
+
connecting.
|
| 320 |
+
- timeout: timeout (in seconds) used for socket connections
|
| 321 |
+
|
| 322 |
+
readermode is sometimes necessary if you are connecting to an
|
| 323 |
+
NNTP server on the local machine and intend to call
|
| 324 |
+
reader-specific commands, such as `group'. If you get
|
| 325 |
+
unexpected NNTPPermanentErrors, you might need to set
|
| 326 |
+
readermode.
|
| 327 |
+
"""
|
| 328 |
+
self.host = host
|
| 329 |
+
self.file = file
|
| 330 |
+
self.debugging = 0
|
| 331 |
+
self.welcome = self._getresp()
|
| 332 |
+
|
| 333 |
+
# Inquire about capabilities (RFC 3977).
|
| 334 |
+
self._caps = None
|
| 335 |
+
self.getcapabilities()
|
| 336 |
+
|
| 337 |
+
# 'MODE READER' is sometimes necessary to enable 'reader' mode.
|
| 338 |
+
# However, the order in which 'MODE READER' and 'AUTHINFO' need to
|
| 339 |
+
# arrive differs between some NNTP servers. If _setreadermode() fails
|
| 340 |
+
# with an authorization failed error, it will set this to True;
|
| 341 |
+
# the login() routine will interpret that as a request to try again
|
| 342 |
+
# after performing its normal function.
|
| 343 |
+
# Enable only if we're not already in READER mode anyway.
|
| 344 |
+
self.readermode_afterauth = False
|
| 345 |
+
if readermode and 'READER' not in self._caps:
|
| 346 |
+
self._setreadermode()
|
| 347 |
+
if not self.readermode_afterauth:
|
| 348 |
+
# Capabilities might have changed after MODE READER
|
| 349 |
+
self._caps = None
|
| 350 |
+
self.getcapabilities()
|
| 351 |
+
|
| 352 |
+
# RFC 4642 2.2.2: Both the client and the server MUST know if there is
|
| 353 |
+
# a TLS session active. A client MUST NOT attempt to start a TLS
|
| 354 |
+
# session if a TLS session is already active.
|
| 355 |
+
self.tls_on = False
|
| 356 |
+
|
| 357 |
+
# Log in and encryption setup order is left to subclasses.
|
| 358 |
+
self.authenticated = False
|
| 359 |
+
|
| 360 |
+
def __enter__(self):
|
| 361 |
+
return self
|
| 362 |
+
|
| 363 |
+
def __exit__(self, *args):
|
| 364 |
+
is_connected = lambda: hasattr(self, "file")
|
| 365 |
+
if is_connected():
|
| 366 |
+
try:
|
| 367 |
+
self.quit()
|
| 368 |
+
except (OSError, EOFError):
|
| 369 |
+
pass
|
| 370 |
+
finally:
|
| 371 |
+
if is_connected():
|
| 372 |
+
self._close()
|
| 373 |
+
|
| 374 |
+
def getwelcome(self):
|
| 375 |
+
"""Get the welcome message from the server
|
| 376 |
+
(this is read and squirreled away by __init__()).
|
| 377 |
+
If the response code is 200, posting is allowed;
|
| 378 |
+
if it 201, posting is not allowed."""
|
| 379 |
+
|
| 380 |
+
if self.debugging: print('*welcome*', repr(self.welcome))
|
| 381 |
+
return self.welcome
|
| 382 |
+
|
| 383 |
+
def getcapabilities(self):
|
| 384 |
+
"""Get the server capabilities, as read by __init__().
|
| 385 |
+
If the CAPABILITIES command is not supported, an empty dict is
|
| 386 |
+
returned."""
|
| 387 |
+
if self._caps is None:
|
| 388 |
+
self.nntp_version = 1
|
| 389 |
+
self.nntp_implementation = None
|
| 390 |
+
try:
|
| 391 |
+
resp, caps = self.capabilities()
|
| 392 |
+
except (NNTPPermanentError, NNTPTemporaryError):
|
| 393 |
+
# Server doesn't support capabilities
|
| 394 |
+
self._caps = {}
|
| 395 |
+
else:
|
| 396 |
+
self._caps = caps
|
| 397 |
+
if 'VERSION' in caps:
|
| 398 |
+
# The server can advertise several supported versions,
|
| 399 |
+
# choose the highest.
|
| 400 |
+
self.nntp_version = max(map(int, caps['VERSION']))
|
| 401 |
+
if 'IMPLEMENTATION' in caps:
|
| 402 |
+
self.nntp_implementation = ' '.join(caps['IMPLEMENTATION'])
|
| 403 |
+
return self._caps
|
| 404 |
+
|
| 405 |
+
def set_debuglevel(self, level):
|
| 406 |
+
"""Set the debugging level. Argument 'level' means:
|
| 407 |
+
0: no debugging output (default)
|
| 408 |
+
1: print commands and responses but not body text etc.
|
| 409 |
+
2: also print raw lines read and sent before stripping CR/LF"""
|
| 410 |
+
|
| 411 |
+
self.debugging = level
|
| 412 |
+
debug = set_debuglevel
|
| 413 |
+
|
| 414 |
+
def _putline(self, line):
|
| 415 |
+
"""Internal: send one line to the server, appending CRLF.
|
| 416 |
+
The `line` must be a bytes-like object."""
|
| 417 |
+
sys.audit("nntplib.putline", self, line)
|
| 418 |
+
line = line + _CRLF
|
| 419 |
+
if self.debugging > 1: print('*put*', repr(line))
|
| 420 |
+
self.file.write(line)
|
| 421 |
+
self.file.flush()
|
| 422 |
+
|
| 423 |
+
def _putcmd(self, line):
|
| 424 |
+
"""Internal: send one command to the server (through _putline()).
|
| 425 |
+
The `line` must be a unicode string."""
|
| 426 |
+
if self.debugging: print('*cmd*', repr(line))
|
| 427 |
+
line = line.encode(self.encoding, self.errors)
|
| 428 |
+
self._putline(line)
|
| 429 |
+
|
| 430 |
+
def _getline(self, strip_crlf=True):
|
| 431 |
+
"""Internal: return one line from the server, stripping _CRLF.
|
| 432 |
+
Raise EOFError if the connection is closed.
|
| 433 |
+
Returns a bytes object."""
|
| 434 |
+
line = self.file.readline(_MAXLINE +1)
|
| 435 |
+
if len(line) > _MAXLINE:
|
| 436 |
+
raise NNTPDataError('line too long')
|
| 437 |
+
if self.debugging > 1:
|
| 438 |
+
print('*get*', repr(line))
|
| 439 |
+
if not line: raise EOFError
|
| 440 |
+
if strip_crlf:
|
| 441 |
+
if line[-2:] == _CRLF:
|
| 442 |
+
line = line[:-2]
|
| 443 |
+
elif line[-1:] in _CRLF:
|
| 444 |
+
line = line[:-1]
|
| 445 |
+
return line
|
| 446 |
+
|
| 447 |
+
def _getresp(self):
|
| 448 |
+
"""Internal: get a response from the server.
|
| 449 |
+
Raise various errors if the response indicates an error.
|
| 450 |
+
Returns a unicode string."""
|
| 451 |
+
resp = self._getline()
|
| 452 |
+
if self.debugging: print('*resp*', repr(resp))
|
| 453 |
+
resp = resp.decode(self.encoding, self.errors)
|
| 454 |
+
c = resp[:1]
|
| 455 |
+
if c == '4':
|
| 456 |
+
raise NNTPTemporaryError(resp)
|
| 457 |
+
if c == '5':
|
| 458 |
+
raise NNTPPermanentError(resp)
|
| 459 |
+
if c not in '123':
|
| 460 |
+
raise NNTPProtocolError(resp)
|
| 461 |
+
return resp
|
| 462 |
+
|
| 463 |
+
def _getlongresp(self, file=None):
|
| 464 |
+
"""Internal: get a response plus following text from the server.
|
| 465 |
+
Raise various errors if the response indicates an error.
|
| 466 |
+
|
| 467 |
+
Returns a (response, lines) tuple where `response` is a unicode
|
| 468 |
+
string and `lines` is a list of bytes objects.
|
| 469 |
+
If `file` is a file-like object, it must be open in binary mode.
|
| 470 |
+
"""
|
| 471 |
+
|
| 472 |
+
openedFile = None
|
| 473 |
+
try:
|
| 474 |
+
# If a string was passed then open a file with that name
|
| 475 |
+
if isinstance(file, (str, bytes)):
|
| 476 |
+
openedFile = file = open(file, "wb")
|
| 477 |
+
|
| 478 |
+
resp = self._getresp()
|
| 479 |
+
if resp[:3] not in _LONGRESP:
|
| 480 |
+
raise NNTPReplyError(resp)
|
| 481 |
+
|
| 482 |
+
lines = []
|
| 483 |
+
if file is not None:
|
| 484 |
+
# XXX lines = None instead?
|
| 485 |
+
terminators = (b'.' + _CRLF, b'.\n')
|
| 486 |
+
while 1:
|
| 487 |
+
line = self._getline(False)
|
| 488 |
+
if line in terminators:
|
| 489 |
+
break
|
| 490 |
+
if line.startswith(b'..'):
|
| 491 |
+
line = line[1:]
|
| 492 |
+
file.write(line)
|
| 493 |
+
else:
|
| 494 |
+
terminator = b'.'
|
| 495 |
+
while 1:
|
| 496 |
+
line = self._getline()
|
| 497 |
+
if line == terminator:
|
| 498 |
+
break
|
| 499 |
+
if line.startswith(b'..'):
|
| 500 |
+
line = line[1:]
|
| 501 |
+
lines.append(line)
|
| 502 |
+
finally:
|
| 503 |
+
# If this method created the file, then it must close it
|
| 504 |
+
if openedFile:
|
| 505 |
+
openedFile.close()
|
| 506 |
+
|
| 507 |
+
return resp, lines
|
| 508 |
+
|
| 509 |
+
def _shortcmd(self, line):
|
| 510 |
+
"""Internal: send a command and get the response.
|
| 511 |
+
Same return value as _getresp()."""
|
| 512 |
+
self._putcmd(line)
|
| 513 |
+
return self._getresp()
|
| 514 |
+
|
| 515 |
+
def _longcmd(self, line, file=None):
|
| 516 |
+
"""Internal: send a command and get the response plus following text.
|
| 517 |
+
Same return value as _getlongresp()."""
|
| 518 |
+
self._putcmd(line)
|
| 519 |
+
return self._getlongresp(file)
|
| 520 |
+
|
| 521 |
+
def _longcmdstring(self, line, file=None):
|
| 522 |
+
"""Internal: send a command and get the response plus following text.
|
| 523 |
+
Same as _longcmd() and _getlongresp(), except that the returned `lines`
|
| 524 |
+
are unicode strings rather than bytes objects.
|
| 525 |
+
"""
|
| 526 |
+
self._putcmd(line)
|
| 527 |
+
resp, list = self._getlongresp(file)
|
| 528 |
+
return resp, [line.decode(self.encoding, self.errors)
|
| 529 |
+
for line in list]
|
| 530 |
+
|
| 531 |
+
def _getoverviewfmt(self):
|
| 532 |
+
"""Internal: get the overview format. Queries the server if not
|
| 533 |
+
already done, else returns the cached value."""
|
| 534 |
+
try:
|
| 535 |
+
return self._cachedoverviewfmt
|
| 536 |
+
except AttributeError:
|
| 537 |
+
pass
|
| 538 |
+
try:
|
| 539 |
+
resp, lines = self._longcmdstring("LIST OVERVIEW.FMT")
|
| 540 |
+
except NNTPPermanentError:
|
| 541 |
+
# Not supported by server?
|
| 542 |
+
fmt = _DEFAULT_OVERVIEW_FMT[:]
|
| 543 |
+
else:
|
| 544 |
+
fmt = _parse_overview_fmt(lines)
|
| 545 |
+
self._cachedoverviewfmt = fmt
|
| 546 |
+
return fmt
|
| 547 |
+
|
| 548 |
+
def _grouplist(self, lines):
|
| 549 |
+
# Parse lines into "group last first flag"
|
| 550 |
+
return [GroupInfo(*line.split()) for line in lines]
|
| 551 |
+
|
| 552 |
+
def capabilities(self):
|
| 553 |
+
"""Process a CAPABILITIES command. Not supported by all servers.
|
| 554 |
+
Return:
|
| 555 |
+
- resp: server response if successful
|
| 556 |
+
- caps: a dictionary mapping capability names to lists of tokens
|
| 557 |
+
(for example {'VERSION': ['2'], 'OVER': [], LIST: ['ACTIVE', 'HEADERS'] })
|
| 558 |
+
"""
|
| 559 |
+
caps = {}
|
| 560 |
+
resp, lines = self._longcmdstring("CAPABILITIES")
|
| 561 |
+
for line in lines:
|
| 562 |
+
name, *tokens = line.split()
|
| 563 |
+
caps[name] = tokens
|
| 564 |
+
return resp, caps
|
| 565 |
+
|
| 566 |
+
def newgroups(self, date, *, file=None):
|
| 567 |
+
"""Process a NEWGROUPS command. Arguments:
|
| 568 |
+
- date: a date or datetime object
|
| 569 |
+
Return:
|
| 570 |
+
- resp: server response if successful
|
| 571 |
+
- list: list of newsgroup names
|
| 572 |
+
"""
|
| 573 |
+
if not isinstance(date, (datetime.date, datetime.date)):
|
| 574 |
+
raise TypeError(
|
| 575 |
+
"the date parameter must be a date or datetime object, "
|
| 576 |
+
"not '{:40}'".format(date.__class__.__name__))
|
| 577 |
+
date_str, time_str = _unparse_datetime(date, self.nntp_version < 2)
|
| 578 |
+
cmd = 'NEWGROUPS {0} {1}'.format(date_str, time_str)
|
| 579 |
+
resp, lines = self._longcmdstring(cmd, file)
|
| 580 |
+
return resp, self._grouplist(lines)
|
| 581 |
+
|
| 582 |
+
def newnews(self, group, date, *, file=None):
|
| 583 |
+
"""Process a NEWNEWS command. Arguments:
|
| 584 |
+
- group: group name or '*'
|
| 585 |
+
- date: a date or datetime object
|
| 586 |
+
Return:
|
| 587 |
+
- resp: server response if successful
|
| 588 |
+
- list: list of message ids
|
| 589 |
+
"""
|
| 590 |
+
if not isinstance(date, (datetime.date, datetime.date)):
|
| 591 |
+
raise TypeError(
|
| 592 |
+
"the date parameter must be a date or datetime object, "
|
| 593 |
+
"not '{:40}'".format(date.__class__.__name__))
|
| 594 |
+
date_str, time_str = _unparse_datetime(date, self.nntp_version < 2)
|
| 595 |
+
cmd = 'NEWNEWS {0} {1} {2}'.format(group, date_str, time_str)
|
| 596 |
+
return self._longcmdstring(cmd, file)
|
| 597 |
+
|
| 598 |
+
def list(self, group_pattern=None, *, file=None):
|
| 599 |
+
"""Process a LIST or LIST ACTIVE command. Arguments:
|
| 600 |
+
- group_pattern: a pattern indicating which groups to query
|
| 601 |
+
- file: Filename string or file object to store the result in
|
| 602 |
+
Returns:
|
| 603 |
+
- resp: server response if successful
|
| 604 |
+
- list: list of (group, last, first, flag) (strings)
|
| 605 |
+
"""
|
| 606 |
+
if group_pattern is not None:
|
| 607 |
+
command = 'LIST ACTIVE ' + group_pattern
|
| 608 |
+
else:
|
| 609 |
+
command = 'LIST'
|
| 610 |
+
resp, lines = self._longcmdstring(command, file)
|
| 611 |
+
return resp, self._grouplist(lines)
|
| 612 |
+
|
| 613 |
+
def _getdescriptions(self, group_pattern, return_all):
|
| 614 |
+
line_pat = re.compile('^(?P<group>[^ \t]+)[ \t]+(.*)$')
|
| 615 |
+
# Try the more std (acc. to RFC2980) LIST NEWSGROUPS first
|
| 616 |
+
resp, lines = self._longcmdstring('LIST NEWSGROUPS ' + group_pattern)
|
| 617 |
+
if not resp.startswith('215'):
|
| 618 |
+
# Now the deprecated XGTITLE. This either raises an error
|
| 619 |
+
# or succeeds with the same output structure as LIST
|
| 620 |
+
# NEWSGROUPS.
|
| 621 |
+
resp, lines = self._longcmdstring('XGTITLE ' + group_pattern)
|
| 622 |
+
groups = {}
|
| 623 |
+
for raw_line in lines:
|
| 624 |
+
match = line_pat.search(raw_line.strip())
|
| 625 |
+
if match:
|
| 626 |
+
name, desc = match.group(1, 2)
|
| 627 |
+
if not return_all:
|
| 628 |
+
return desc
|
| 629 |
+
groups[name] = desc
|
| 630 |
+
if return_all:
|
| 631 |
+
return resp, groups
|
| 632 |
+
else:
|
| 633 |
+
# Nothing found
|
| 634 |
+
return ''
|
| 635 |
+
|
| 636 |
+
def description(self, group):
|
| 637 |
+
"""Get a description for a single group. If more than one
|
| 638 |
+
group matches ('group' is a pattern), return the first. If no
|
| 639 |
+
group matches, return an empty string.
|
| 640 |
+
|
| 641 |
+
This elides the response code from the server, since it can
|
| 642 |
+
only be '215' or '285' (for xgtitle) anyway. If the response
|
| 643 |
+
code is needed, use the 'descriptions' method.
|
| 644 |
+
|
| 645 |
+
NOTE: This neither checks for a wildcard in 'group' nor does
|
| 646 |
+
it check whether the group actually exists."""
|
| 647 |
+
return self._getdescriptions(group, False)
|
| 648 |
+
|
| 649 |
+
def descriptions(self, group_pattern):
|
| 650 |
+
"""Get descriptions for a range of groups."""
|
| 651 |
+
return self._getdescriptions(group_pattern, True)
|
| 652 |
+
|
| 653 |
+
def group(self, name):
|
| 654 |
+
"""Process a GROUP command. Argument:
|
| 655 |
+
- group: the group name
|
| 656 |
+
Returns:
|
| 657 |
+
- resp: server response if successful
|
| 658 |
+
- count: number of articles
|
| 659 |
+
- first: first article number
|
| 660 |
+
- last: last article number
|
| 661 |
+
- name: the group name
|
| 662 |
+
"""
|
| 663 |
+
resp = self._shortcmd('GROUP ' + name)
|
| 664 |
+
if not resp.startswith('211'):
|
| 665 |
+
raise NNTPReplyError(resp)
|
| 666 |
+
words = resp.split()
|
| 667 |
+
count = first = last = 0
|
| 668 |
+
n = len(words)
|
| 669 |
+
if n > 1:
|
| 670 |
+
count = words[1]
|
| 671 |
+
if n > 2:
|
| 672 |
+
first = words[2]
|
| 673 |
+
if n > 3:
|
| 674 |
+
last = words[3]
|
| 675 |
+
if n > 4:
|
| 676 |
+
name = words[4].lower()
|
| 677 |
+
return resp, int(count), int(first), int(last), name
|
| 678 |
+
|
| 679 |
+
def help(self, *, file=None):
|
| 680 |
+
"""Process a HELP command. Argument:
|
| 681 |
+
- file: Filename string or file object to store the result in
|
| 682 |
+
Returns:
|
| 683 |
+
- resp: server response if successful
|
| 684 |
+
- list: list of strings returned by the server in response to the
|
| 685 |
+
HELP command
|
| 686 |
+
"""
|
| 687 |
+
return self._longcmdstring('HELP', file)
|
| 688 |
+
|
| 689 |
+
def _statparse(self, resp):
|
| 690 |
+
"""Internal: parse the response line of a STAT, NEXT, LAST,
|
| 691 |
+
ARTICLE, HEAD or BODY command."""
|
| 692 |
+
if not resp.startswith('22'):
|
| 693 |
+
raise NNTPReplyError(resp)
|
| 694 |
+
words = resp.split()
|
| 695 |
+
art_num = int(words[1])
|
| 696 |
+
message_id = words[2]
|
| 697 |
+
return resp, art_num, message_id
|
| 698 |
+
|
| 699 |
+
def _statcmd(self, line):
|
| 700 |
+
"""Internal: process a STAT, NEXT or LAST command."""
|
| 701 |
+
resp = self._shortcmd(line)
|
| 702 |
+
return self._statparse(resp)
|
| 703 |
+
|
| 704 |
+
def stat(self, message_spec=None):
|
| 705 |
+
"""Process a STAT command. Argument:
|
| 706 |
+
- message_spec: article number or message id (if not specified,
|
| 707 |
+
the current article is selected)
|
| 708 |
+
Returns:
|
| 709 |
+
- resp: server response if successful
|
| 710 |
+
- art_num: the article number
|
| 711 |
+
- message_id: the message id
|
| 712 |
+
"""
|
| 713 |
+
if message_spec:
|
| 714 |
+
return self._statcmd('STAT {0}'.format(message_spec))
|
| 715 |
+
else:
|
| 716 |
+
return self._statcmd('STAT')
|
| 717 |
+
|
| 718 |
+
def next(self):
|
| 719 |
+
"""Process a NEXT command. No arguments. Return as for STAT."""
|
| 720 |
+
return self._statcmd('NEXT')
|
| 721 |
+
|
| 722 |
+
def last(self):
|
| 723 |
+
"""Process a LAST command. No arguments. Return as for STAT."""
|
| 724 |
+
return self._statcmd('LAST')
|
| 725 |
+
|
| 726 |
+
def _artcmd(self, line, file=None):
|
| 727 |
+
"""Internal: process a HEAD, BODY or ARTICLE command."""
|
| 728 |
+
resp, lines = self._longcmd(line, file)
|
| 729 |
+
resp, art_num, message_id = self._statparse(resp)
|
| 730 |
+
return resp, ArticleInfo(art_num, message_id, lines)
|
| 731 |
+
|
| 732 |
+
def head(self, message_spec=None, *, file=None):
|
| 733 |
+
"""Process a HEAD command. Argument:
|
| 734 |
+
- message_spec: article number or message id
|
| 735 |
+
- file: filename string or file object to store the headers in
|
| 736 |
+
Returns:
|
| 737 |
+
- resp: server response if successful
|
| 738 |
+
- ArticleInfo: (article number, message id, list of header lines)
|
| 739 |
+
"""
|
| 740 |
+
if message_spec is not None:
|
| 741 |
+
cmd = 'HEAD {0}'.format(message_spec)
|
| 742 |
+
else:
|
| 743 |
+
cmd = 'HEAD'
|
| 744 |
+
return self._artcmd(cmd, file)
|
| 745 |
+
|
| 746 |
+
def body(self, message_spec=None, *, file=None):
|
| 747 |
+
"""Process a BODY command. Argument:
|
| 748 |
+
- message_spec: article number or message id
|
| 749 |
+
- file: filename string or file object to store the body in
|
| 750 |
+
Returns:
|
| 751 |
+
- resp: server response if successful
|
| 752 |
+
- ArticleInfo: (article number, message id, list of body lines)
|
| 753 |
+
"""
|
| 754 |
+
if message_spec is not None:
|
| 755 |
+
cmd = 'BODY {0}'.format(message_spec)
|
| 756 |
+
else:
|
| 757 |
+
cmd = 'BODY'
|
| 758 |
+
return self._artcmd(cmd, file)
|
| 759 |
+
|
| 760 |
+
def article(self, message_spec=None, *, file=None):
|
| 761 |
+
"""Process an ARTICLE command. Argument:
|
| 762 |
+
- message_spec: article number or message id
|
| 763 |
+
- file: filename string or file object to store the article in
|
| 764 |
+
Returns:
|
| 765 |
+
- resp: server response if successful
|
| 766 |
+
- ArticleInfo: (article number, message id, list of article lines)
|
| 767 |
+
"""
|
| 768 |
+
if message_spec is not None:
|
| 769 |
+
cmd = 'ARTICLE {0}'.format(message_spec)
|
| 770 |
+
else:
|
| 771 |
+
cmd = 'ARTICLE'
|
| 772 |
+
return self._artcmd(cmd, file)
|
| 773 |
+
|
| 774 |
+
def slave(self):
|
| 775 |
+
"""Process a SLAVE command. Returns:
|
| 776 |
+
- resp: server response if successful
|
| 777 |
+
"""
|
| 778 |
+
return self._shortcmd('SLAVE')
|
| 779 |
+
|
| 780 |
+
def xhdr(self, hdr, str, *, file=None):
|
| 781 |
+
"""Process an XHDR command (optional server extension). Arguments:
|
| 782 |
+
- hdr: the header type (e.g. 'subject')
|
| 783 |
+
- str: an article nr, a message id, or a range nr1-nr2
|
| 784 |
+
- file: Filename string or file object to store the result in
|
| 785 |
+
Returns:
|
| 786 |
+
- resp: server response if successful
|
| 787 |
+
- list: list of (nr, value) strings
|
| 788 |
+
"""
|
| 789 |
+
pat = re.compile('^([0-9]+) ?(.*)\n?')
|
| 790 |
+
resp, lines = self._longcmdstring('XHDR {0} {1}'.format(hdr, str), file)
|
| 791 |
+
def remove_number(line):
|
| 792 |
+
m = pat.match(line)
|
| 793 |
+
return m.group(1, 2) if m else line
|
| 794 |
+
return resp, [remove_number(line) for line in lines]
|
| 795 |
+
|
| 796 |
+
def xover(self, start, end, *, file=None):
|
| 797 |
+
"""Process an XOVER command (optional server extension) Arguments:
|
| 798 |
+
- start: start of range
|
| 799 |
+
- end: end of range
|
| 800 |
+
- file: Filename string or file object to store the result in
|
| 801 |
+
Returns:
|
| 802 |
+
- resp: server response if successful
|
| 803 |
+
- list: list of dicts containing the response fields
|
| 804 |
+
"""
|
| 805 |
+
resp, lines = self._longcmdstring('XOVER {0}-{1}'.format(start, end),
|
| 806 |
+
file)
|
| 807 |
+
fmt = self._getoverviewfmt()
|
| 808 |
+
return resp, _parse_overview(lines, fmt)
|
| 809 |
+
|
| 810 |
+
def over(self, message_spec, *, file=None):
|
| 811 |
+
"""Process an OVER command. If the command isn't supported, fall
|
| 812 |
+
back to XOVER. Arguments:
|
| 813 |
+
- message_spec:
|
| 814 |
+
- either a message id, indicating the article to fetch
|
| 815 |
+
information about
|
| 816 |
+
- or a (start, end) tuple, indicating a range of article numbers;
|
| 817 |
+
if end is None, information up to the newest message will be
|
| 818 |
+
retrieved
|
| 819 |
+
- or None, indicating the current article number must be used
|
| 820 |
+
- file: Filename string or file object to store the result in
|
| 821 |
+
Returns:
|
| 822 |
+
- resp: server response if successful
|
| 823 |
+
- list: list of dicts containing the response fields
|
| 824 |
+
|
| 825 |
+
NOTE: the "message id" form isn't supported by XOVER
|
| 826 |
+
"""
|
| 827 |
+
cmd = 'OVER' if 'OVER' in self._caps else 'XOVER'
|
| 828 |
+
if isinstance(message_spec, (tuple, list)):
|
| 829 |
+
start, end = message_spec
|
| 830 |
+
cmd += ' {0}-{1}'.format(start, end or '')
|
| 831 |
+
elif message_spec is not None:
|
| 832 |
+
cmd = cmd + ' ' + message_spec
|
| 833 |
+
resp, lines = self._longcmdstring(cmd, file)
|
| 834 |
+
fmt = self._getoverviewfmt()
|
| 835 |
+
return resp, _parse_overview(lines, fmt)
|
| 836 |
+
|
| 837 |
+
def xgtitle(self, group, *, file=None):
|
| 838 |
+
"""Process an XGTITLE command (optional server extension) Arguments:
|
| 839 |
+
- group: group name wildcard (i.e. news.*)
|
| 840 |
+
Returns:
|
| 841 |
+
- resp: server response if successful
|
| 842 |
+
- list: list of (name,title) strings"""
|
| 843 |
+
warnings.warn("The XGTITLE extension is not actively used, "
|
| 844 |
+
"use descriptions() instead",
|
| 845 |
+
DeprecationWarning, 2)
|
| 846 |
+
line_pat = re.compile('^([^ \t]+)[ \t]+(.*)$')
|
| 847 |
+
resp, raw_lines = self._longcmdstring('XGTITLE ' + group, file)
|
| 848 |
+
lines = []
|
| 849 |
+
for raw_line in raw_lines:
|
| 850 |
+
match = line_pat.search(raw_line.strip())
|
| 851 |
+
if match:
|
| 852 |
+
lines.append(match.group(1, 2))
|
| 853 |
+
return resp, lines
|
| 854 |
+
|
| 855 |
+
def xpath(self, id):
|
| 856 |
+
"""Process an XPATH command (optional server extension) Arguments:
|
| 857 |
+
- id: Message id of article
|
| 858 |
+
Returns:
|
| 859 |
+
resp: server response if successful
|
| 860 |
+
path: directory path to article
|
| 861 |
+
"""
|
| 862 |
+
warnings.warn("The XPATH extension is not actively used",
|
| 863 |
+
DeprecationWarning, 2)
|
| 864 |
+
|
| 865 |
+
resp = self._shortcmd('XPATH {0}'.format(id))
|
| 866 |
+
if not resp.startswith('223'):
|
| 867 |
+
raise NNTPReplyError(resp)
|
| 868 |
+
try:
|
| 869 |
+
[resp_num, path] = resp.split()
|
| 870 |
+
except ValueError:
|
| 871 |
+
raise NNTPReplyError(resp) from None
|
| 872 |
+
else:
|
| 873 |
+
return resp, path
|
| 874 |
+
|
| 875 |
+
def date(self):
|
| 876 |
+
"""Process the DATE command.
|
| 877 |
+
Returns:
|
| 878 |
+
- resp: server response if successful
|
| 879 |
+
- date: datetime object
|
| 880 |
+
"""
|
| 881 |
+
resp = self._shortcmd("DATE")
|
| 882 |
+
if not resp.startswith('111'):
|
| 883 |
+
raise NNTPReplyError(resp)
|
| 884 |
+
elem = resp.split()
|
| 885 |
+
if len(elem) != 2:
|
| 886 |
+
raise NNTPDataError(resp)
|
| 887 |
+
date = elem[1]
|
| 888 |
+
if len(date) != 14:
|
| 889 |
+
raise NNTPDataError(resp)
|
| 890 |
+
return resp, _parse_datetime(date, None)
|
| 891 |
+
|
| 892 |
+
def _post(self, command, f):
|
| 893 |
+
resp = self._shortcmd(command)
|
| 894 |
+
# Raises a specific exception if posting is not allowed
|
| 895 |
+
if not resp.startswith('3'):
|
| 896 |
+
raise NNTPReplyError(resp)
|
| 897 |
+
if isinstance(f, (bytes, bytearray)):
|
| 898 |
+
f = f.splitlines()
|
| 899 |
+
# We don't use _putline() because:
|
| 900 |
+
# - we don't want additional CRLF if the file or iterable is already
|
| 901 |
+
# in the right format
|
| 902 |
+
# - we don't want a spurious flush() after each line is written
|
| 903 |
+
for line in f:
|
| 904 |
+
if not line.endswith(_CRLF):
|
| 905 |
+
line = line.rstrip(b"\r\n") + _CRLF
|
| 906 |
+
if line.startswith(b'.'):
|
| 907 |
+
line = b'.' + line
|
| 908 |
+
self.file.write(line)
|
| 909 |
+
self.file.write(b".\r\n")
|
| 910 |
+
self.file.flush()
|
| 911 |
+
return self._getresp()
|
| 912 |
+
|
| 913 |
+
def post(self, data):
|
| 914 |
+
"""Process a POST command. Arguments:
|
| 915 |
+
- data: bytes object, iterable or file containing the article
|
| 916 |
+
Returns:
|
| 917 |
+
- resp: server response if successful"""
|
| 918 |
+
return self._post('POST', data)
|
| 919 |
+
|
| 920 |
+
def ihave(self, message_id, data):
|
| 921 |
+
"""Process an IHAVE command. Arguments:
|
| 922 |
+
- message_id: message-id of the article
|
| 923 |
+
- data: file containing the article
|
| 924 |
+
Returns:
|
| 925 |
+
- resp: server response if successful
|
| 926 |
+
Note that if the server refuses the article an exception is raised."""
|
| 927 |
+
return self._post('IHAVE {0}'.format(message_id), data)
|
| 928 |
+
|
| 929 |
+
def _close(self):
|
| 930 |
+
self.file.close()
|
| 931 |
+
del self.file
|
| 932 |
+
|
| 933 |
+
def quit(self):
|
| 934 |
+
"""Process a QUIT command and close the socket. Returns:
|
| 935 |
+
- resp: server response if successful"""
|
| 936 |
+
try:
|
| 937 |
+
resp = self._shortcmd('QUIT')
|
| 938 |
+
finally:
|
| 939 |
+
self._close()
|
| 940 |
+
return resp
|
| 941 |
+
|
| 942 |
+
def login(self, user=None, password=None, usenetrc=True):
|
| 943 |
+
if self.authenticated:
|
| 944 |
+
raise ValueError("Already logged in.")
|
| 945 |
+
if not user and not usenetrc:
|
| 946 |
+
raise ValueError(
|
| 947 |
+
"At least one of `user` and `usenetrc` must be specified")
|
| 948 |
+
# If no login/password was specified but netrc was requested,
|
| 949 |
+
# try to get them from ~/.netrc
|
| 950 |
+
# Presume that if .netrc has an entry, NNRP authentication is required.
|
| 951 |
+
try:
|
| 952 |
+
if usenetrc and not user:
|
| 953 |
+
import netrc
|
| 954 |
+
credentials = netrc.netrc()
|
| 955 |
+
auth = credentials.authenticators(self.host)
|
| 956 |
+
if auth:
|
| 957 |
+
user = auth[0]
|
| 958 |
+
password = auth[2]
|
| 959 |
+
except OSError:
|
| 960 |
+
pass
|
| 961 |
+
# Perform NNTP authentication if needed.
|
| 962 |
+
if not user:
|
| 963 |
+
return
|
| 964 |
+
resp = self._shortcmd('authinfo user ' + user)
|
| 965 |
+
if resp.startswith('381'):
|
| 966 |
+
if not password:
|
| 967 |
+
raise NNTPReplyError(resp)
|
| 968 |
+
else:
|
| 969 |
+
resp = self._shortcmd('authinfo pass ' + password)
|
| 970 |
+
if not resp.startswith('281'):
|
| 971 |
+
raise NNTPPermanentError(resp)
|
| 972 |
+
# Capabilities might have changed after login
|
| 973 |
+
self._caps = None
|
| 974 |
+
self.getcapabilities()
|
| 975 |
+
# Attempt to send mode reader if it was requested after login.
|
| 976 |
+
# Only do so if we're not in reader mode already.
|
| 977 |
+
if self.readermode_afterauth and 'READER' not in self._caps:
|
| 978 |
+
self._setreadermode()
|
| 979 |
+
# Capabilities might have changed after MODE READER
|
| 980 |
+
self._caps = None
|
| 981 |
+
self.getcapabilities()
|
| 982 |
+
|
| 983 |
+
def _setreadermode(self):
|
| 984 |
+
try:
|
| 985 |
+
self.welcome = self._shortcmd('mode reader')
|
| 986 |
+
except NNTPPermanentError:
|
| 987 |
+
# Error 5xx, probably 'not implemented'
|
| 988 |
+
pass
|
| 989 |
+
except NNTPTemporaryError as e:
|
| 990 |
+
if e.response.startswith('480'):
|
| 991 |
+
# Need authorization before 'mode reader'
|
| 992 |
+
self.readermode_afterauth = True
|
| 993 |
+
else:
|
| 994 |
+
raise
|
| 995 |
+
|
| 996 |
+
if _have_ssl:
|
| 997 |
+
def starttls(self, context=None):
|
| 998 |
+
"""Process a STARTTLS command. Arguments:
|
| 999 |
+
- context: SSL context to use for the encrypted connection
|
| 1000 |
+
"""
|
| 1001 |
+
# Per RFC 4642, STARTTLS MUST NOT be sent after authentication or if
|
| 1002 |
+
# a TLS session already exists.
|
| 1003 |
+
if self.tls_on:
|
| 1004 |
+
raise ValueError("TLS is already enabled.")
|
| 1005 |
+
if self.authenticated:
|
| 1006 |
+
raise ValueError("TLS cannot be started after authentication.")
|
| 1007 |
+
resp = self._shortcmd('STARTTLS')
|
| 1008 |
+
if resp.startswith('382'):
|
| 1009 |
+
self.file.close()
|
| 1010 |
+
self.sock = _encrypt_on(self.sock, context, self.host)
|
| 1011 |
+
self.file = self.sock.makefile("rwb")
|
| 1012 |
+
self.tls_on = True
|
| 1013 |
+
# Capabilities may change after TLS starts up, so ask for them
|
| 1014 |
+
# again.
|
| 1015 |
+
self._caps = None
|
| 1016 |
+
self.getcapabilities()
|
| 1017 |
+
else:
|
| 1018 |
+
raise NNTPError("TLS failed to start.")
|
| 1019 |
+
|
| 1020 |
+
|
| 1021 |
+
class NNTP(_NNTPBase):
|
| 1022 |
+
|
| 1023 |
+
def __init__(self, host, port=NNTP_PORT, user=None, password=None,
|
| 1024 |
+
readermode=None, usenetrc=False,
|
| 1025 |
+
timeout=_GLOBAL_DEFAULT_TIMEOUT):
|
| 1026 |
+
"""Initialize an instance. Arguments:
|
| 1027 |
+
- host: hostname to connect to
|
| 1028 |
+
- port: port to connect to (default the standard NNTP port)
|
| 1029 |
+
- user: username to authenticate with
|
| 1030 |
+
- password: password to use with username
|
| 1031 |
+
- readermode: if true, send 'mode reader' command after
|
| 1032 |
+
connecting.
|
| 1033 |
+
- usenetrc: allow loading username and password from ~/.netrc file
|
| 1034 |
+
if not specified explicitly
|
| 1035 |
+
- timeout: timeout (in seconds) used for socket connections
|
| 1036 |
+
|
| 1037 |
+
readermode is sometimes necessary if you are connecting to an
|
| 1038 |
+
NNTP server on the local machine and intend to call
|
| 1039 |
+
reader-specific commands, such as `group'. If you get
|
| 1040 |
+
unexpected NNTPPermanentErrors, you might need to set
|
| 1041 |
+
readermode.
|
| 1042 |
+
"""
|
| 1043 |
+
self.host = host
|
| 1044 |
+
self.port = port
|
| 1045 |
+
sys.audit("nntplib.connect", self, host, port)
|
| 1046 |
+
self.sock = socket.create_connection((host, port), timeout)
|
| 1047 |
+
file = None
|
| 1048 |
+
try:
|
| 1049 |
+
file = self.sock.makefile("rwb")
|
| 1050 |
+
_NNTPBase.__init__(self, file, host,
|
| 1051 |
+
readermode, timeout)
|
| 1052 |
+
if user or usenetrc:
|
| 1053 |
+
self.login(user, password, usenetrc)
|
| 1054 |
+
except:
|
| 1055 |
+
if file:
|
| 1056 |
+
file.close()
|
| 1057 |
+
self.sock.close()
|
| 1058 |
+
raise
|
| 1059 |
+
|
| 1060 |
+
def _close(self):
|
| 1061 |
+
try:
|
| 1062 |
+
_NNTPBase._close(self)
|
| 1063 |
+
finally:
|
| 1064 |
+
self.sock.close()
|
| 1065 |
+
|
| 1066 |
+
|
| 1067 |
+
if _have_ssl:
|
| 1068 |
+
class NNTP_SSL(_NNTPBase):
|
| 1069 |
+
|
| 1070 |
+
def __init__(self, host, port=NNTP_SSL_PORT,
|
| 1071 |
+
user=None, password=None, ssl_context=None,
|
| 1072 |
+
readermode=None, usenetrc=False,
|
| 1073 |
+
timeout=_GLOBAL_DEFAULT_TIMEOUT):
|
| 1074 |
+
"""This works identically to NNTP.__init__, except for the change
|
| 1075 |
+
in default port and the `ssl_context` argument for SSL connections.
|
| 1076 |
+
"""
|
| 1077 |
+
sys.audit("nntplib.connect", self, host, port)
|
| 1078 |
+
self.sock = socket.create_connection((host, port), timeout)
|
| 1079 |
+
file = None
|
| 1080 |
+
try:
|
| 1081 |
+
self.sock = _encrypt_on(self.sock, ssl_context, host)
|
| 1082 |
+
file = self.sock.makefile("rwb")
|
| 1083 |
+
_NNTPBase.__init__(self, file, host,
|
| 1084 |
+
readermode=readermode, timeout=timeout)
|
| 1085 |
+
if user or usenetrc:
|
| 1086 |
+
self.login(user, password, usenetrc)
|
| 1087 |
+
except:
|
| 1088 |
+
if file:
|
| 1089 |
+
file.close()
|
| 1090 |
+
self.sock.close()
|
| 1091 |
+
raise
|
| 1092 |
+
|
| 1093 |
+
def _close(self):
|
| 1094 |
+
try:
|
| 1095 |
+
_NNTPBase._close(self)
|
| 1096 |
+
finally:
|
| 1097 |
+
self.sock.close()
|
| 1098 |
+
|
| 1099 |
+
__all__.append("NNTP_SSL")
|
| 1100 |
+
|
| 1101 |
+
|
| 1102 |
+
# Test retrieval when run as a script.
|
| 1103 |
+
if __name__ == '__main__':
|
| 1104 |
+
import argparse
|
| 1105 |
+
|
| 1106 |
+
parser = argparse.ArgumentParser(description="""\
|
| 1107 |
+
nntplib built-in demo - display the latest articles in a newsgroup""")
|
| 1108 |
+
parser.add_argument('-g', '--group', default='gmane.comp.python.general',
|
| 1109 |
+
help='group to fetch messages from (default: %(default)s)')
|
| 1110 |
+
parser.add_argument('-s', '--server', default='news.gmane.io',
|
| 1111 |
+
help='NNTP server hostname (default: %(default)s)')
|
| 1112 |
+
parser.add_argument('-p', '--port', default=-1, type=int,
|
| 1113 |
+
help='NNTP port number (default: %s / %s)' % (NNTP_PORT, NNTP_SSL_PORT))
|
| 1114 |
+
parser.add_argument('-n', '--nb-articles', default=10, type=int,
|
| 1115 |
+
help='number of articles to fetch (default: %(default)s)')
|
| 1116 |
+
parser.add_argument('-S', '--ssl', action='store_true', default=False,
|
| 1117 |
+
help='use NNTP over SSL')
|
| 1118 |
+
args = parser.parse_args()
|
| 1119 |
+
|
| 1120 |
+
port = args.port
|
| 1121 |
+
if not args.ssl:
|
| 1122 |
+
if port == -1:
|
| 1123 |
+
port = NNTP_PORT
|
| 1124 |
+
s = NNTP(host=args.server, port=port)
|
| 1125 |
+
else:
|
| 1126 |
+
if port == -1:
|
| 1127 |
+
port = NNTP_SSL_PORT
|
| 1128 |
+
s = NNTP_SSL(host=args.server, port=port)
|
| 1129 |
+
|
| 1130 |
+
caps = s.getcapabilities()
|
| 1131 |
+
if 'STARTTLS' in caps:
|
| 1132 |
+
s.starttls()
|
| 1133 |
+
resp, count, first, last, name = s.group(args.group)
|
| 1134 |
+
print('Group', name, 'has', count, 'articles, range', first, 'to', last)
|
| 1135 |
+
|
| 1136 |
+
def cut(s, lim):
|
| 1137 |
+
if len(s) > lim:
|
| 1138 |
+
s = s[:lim - 4] + "..."
|
| 1139 |
+
return s
|
| 1140 |
+
|
| 1141 |
+
first = str(int(last) - args.nb_articles + 1)
|
| 1142 |
+
resp, overviews = s.xover(first, last)
|
| 1143 |
+
for artnum, over in overviews:
|
| 1144 |
+
author = decode_header(over['from']).split('<', 1)[0]
|
| 1145 |
+
subject = decode_header(over['subject'])
|
| 1146 |
+
lines = int(over[':lines'])
|
| 1147 |
+
print("{:7} {:20} {:42} ({})".format(
|
| 1148 |
+
artnum, cut(author, 20), cut(subject, 42), lines)
|
| 1149 |
+
)
|
| 1150 |
+
|
| 1151 |
+
s.quit()
|
my_container_sandbox/workspace/anaconda3/lib/python3.8/numbers.py
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2007 Google, Inc. All Rights Reserved.
|
| 2 |
+
# Licensed to PSF under a Contributor Agreement.
|
| 3 |
+
|
| 4 |
+
"""Abstract Base Classes (ABCs) for numbers, according to PEP 3141.
|
| 5 |
+
|
| 6 |
+
TODO: Fill out more detailed documentation on the operators."""
|
| 7 |
+
|
| 8 |
+
from abc import ABCMeta, abstractmethod
|
| 9 |
+
|
| 10 |
+
__all__ = ["Number", "Complex", "Real", "Rational", "Integral"]
|
| 11 |
+
|
| 12 |
+
class Number(metaclass=ABCMeta):
|
| 13 |
+
"""All numbers inherit from this class.
|
| 14 |
+
|
| 15 |
+
If you just want to check if an argument x is a number, without
|
| 16 |
+
caring what kind, use isinstance(x, Number).
|
| 17 |
+
"""
|
| 18 |
+
__slots__ = ()
|
| 19 |
+
|
| 20 |
+
# Concrete numeric types must provide their own hash implementation
|
| 21 |
+
__hash__ = None
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
## Notes on Decimal
|
| 25 |
+
## ----------------
|
| 26 |
+
## Decimal has all of the methods specified by the Real abc, but it should
|
| 27 |
+
## not be registered as a Real because decimals do not interoperate with
|
| 28 |
+
## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But,
|
| 29 |
+
## abstract reals are expected to interoperate (i.e. R1 + R2 should be
|
| 30 |
+
## expected to work if R1 and R2 are both Reals).
|
| 31 |
+
|
| 32 |
+
class Complex(Number):
|
| 33 |
+
"""Complex defines the operations that work on the builtin complex type.
|
| 34 |
+
|
| 35 |
+
In short, those are: a conversion to complex, .real, .imag, +, -,
|
| 36 |
+
*, /, abs(), .conjugate, ==, and !=.
|
| 37 |
+
|
| 38 |
+
If it is given heterogeneous arguments, and doesn't have special
|
| 39 |
+
knowledge about them, it should fall back to the builtin complex
|
| 40 |
+
type as described below.
|
| 41 |
+
"""
|
| 42 |
+
|
| 43 |
+
__slots__ = ()
|
| 44 |
+
|
| 45 |
+
@abstractmethod
|
| 46 |
+
def __complex__(self):
|
| 47 |
+
"""Return a builtin complex instance. Called for complex(self)."""
|
| 48 |
+
|
| 49 |
+
def __bool__(self):
|
| 50 |
+
"""True if self != 0. Called for bool(self)."""
|
| 51 |
+
return self != 0
|
| 52 |
+
|
| 53 |
+
@property
|
| 54 |
+
@abstractmethod
|
| 55 |
+
def real(self):
|
| 56 |
+
"""Retrieve the real component of this number.
|
| 57 |
+
|
| 58 |
+
This should subclass Real.
|
| 59 |
+
"""
|
| 60 |
+
raise NotImplementedError
|
| 61 |
+
|
| 62 |
+
@property
|
| 63 |
+
@abstractmethod
|
| 64 |
+
def imag(self):
|
| 65 |
+
"""Retrieve the imaginary component of this number.
|
| 66 |
+
|
| 67 |
+
This should subclass Real.
|
| 68 |
+
"""
|
| 69 |
+
raise NotImplementedError
|
| 70 |
+
|
| 71 |
+
@abstractmethod
|
| 72 |
+
def __add__(self, other):
|
| 73 |
+
"""self + other"""
|
| 74 |
+
raise NotImplementedError
|
| 75 |
+
|
| 76 |
+
@abstractmethod
|
| 77 |
+
def __radd__(self, other):
|
| 78 |
+
"""other + self"""
|
| 79 |
+
raise NotImplementedError
|
| 80 |
+
|
| 81 |
+
@abstractmethod
|
| 82 |
+
def __neg__(self):
|
| 83 |
+
"""-self"""
|
| 84 |
+
raise NotImplementedError
|
| 85 |
+
|
| 86 |
+
@abstractmethod
|
| 87 |
+
def __pos__(self):
|
| 88 |
+
"""+self"""
|
| 89 |
+
raise NotImplementedError
|
| 90 |
+
|
| 91 |
+
def __sub__(self, other):
|
| 92 |
+
"""self - other"""
|
| 93 |
+
return self + -other
|
| 94 |
+
|
| 95 |
+
def __rsub__(self, other):
|
| 96 |
+
"""other - self"""
|
| 97 |
+
return -self + other
|
| 98 |
+
|
| 99 |
+
@abstractmethod
|
| 100 |
+
def __mul__(self, other):
|
| 101 |
+
"""self * other"""
|
| 102 |
+
raise NotImplementedError
|
| 103 |
+
|
| 104 |
+
@abstractmethod
|
| 105 |
+
def __rmul__(self, other):
|
| 106 |
+
"""other * self"""
|
| 107 |
+
raise NotImplementedError
|
| 108 |
+
|
| 109 |
+
@abstractmethod
|
| 110 |
+
def __truediv__(self, other):
|
| 111 |
+
"""self / other: Should promote to float when necessary."""
|
| 112 |
+
raise NotImplementedError
|
| 113 |
+
|
| 114 |
+
@abstractmethod
|
| 115 |
+
def __rtruediv__(self, other):
|
| 116 |
+
"""other / self"""
|
| 117 |
+
raise NotImplementedError
|
| 118 |
+
|
| 119 |
+
@abstractmethod
|
| 120 |
+
def __pow__(self, exponent):
|
| 121 |
+
"""self**exponent; should promote to float or complex when necessary."""
|
| 122 |
+
raise NotImplementedError
|
| 123 |
+
|
| 124 |
+
@abstractmethod
|
| 125 |
+
def __rpow__(self, base):
|
| 126 |
+
"""base ** self"""
|
| 127 |
+
raise NotImplementedError
|
| 128 |
+
|
| 129 |
+
@abstractmethod
|
| 130 |
+
def __abs__(self):
|
| 131 |
+
"""Returns the Real distance from 0. Called for abs(self)."""
|
| 132 |
+
raise NotImplementedError
|
| 133 |
+
|
| 134 |
+
@abstractmethod
|
| 135 |
+
def conjugate(self):
|
| 136 |
+
"""(x+y*i).conjugate() returns (x-y*i)."""
|
| 137 |
+
raise NotImplementedError
|
| 138 |
+
|
| 139 |
+
@abstractmethod
|
| 140 |
+
def __eq__(self, other):
|
| 141 |
+
"""self == other"""
|
| 142 |
+
raise NotImplementedError
|
| 143 |
+
|
| 144 |
+
Complex.register(complex)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
class Real(Complex):
|
| 148 |
+
"""To Complex, Real adds the operations that work on real numbers.
|
| 149 |
+
|
| 150 |
+
In short, those are: a conversion to float, trunc(), divmod,
|
| 151 |
+
%, <, <=, >, and >=.
|
| 152 |
+
|
| 153 |
+
Real also provides defaults for the derived operations.
|
| 154 |
+
"""
|
| 155 |
+
|
| 156 |
+
__slots__ = ()
|
| 157 |
+
|
| 158 |
+
@abstractmethod
|
| 159 |
+
def __float__(self):
|
| 160 |
+
"""Any Real can be converted to a native float object.
|
| 161 |
+
|
| 162 |
+
Called for float(self)."""
|
| 163 |
+
raise NotImplementedError
|
| 164 |
+
|
| 165 |
+
@abstractmethod
|
| 166 |
+
def __trunc__(self):
|
| 167 |
+
"""trunc(self): Truncates self to an Integral.
|
| 168 |
+
|
| 169 |
+
Returns an Integral i such that:
|
| 170 |
+
* i>0 iff self>0;
|
| 171 |
+
* abs(i) <= abs(self);
|
| 172 |
+
* for any Integral j satisfying the first two conditions,
|
| 173 |
+
abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
|
| 174 |
+
i.e. "truncate towards 0".
|
| 175 |
+
"""
|
| 176 |
+
raise NotImplementedError
|
| 177 |
+
|
| 178 |
+
@abstractmethod
|
| 179 |
+
def __floor__(self):
|
| 180 |
+
"""Finds the greatest Integral <= self."""
|
| 181 |
+
raise NotImplementedError
|
| 182 |
+
|
| 183 |
+
@abstractmethod
|
| 184 |
+
def __ceil__(self):
|
| 185 |
+
"""Finds the least Integral >= self."""
|
| 186 |
+
raise NotImplementedError
|
| 187 |
+
|
| 188 |
+
@abstractmethod
|
| 189 |
+
def __round__(self, ndigits=None):
|
| 190 |
+
"""Rounds self to ndigits decimal places, defaulting to 0.
|
| 191 |
+
|
| 192 |
+
If ndigits is omitted or None, returns an Integral, otherwise
|
| 193 |
+
returns a Real. Rounds half toward even.
|
| 194 |
+
"""
|
| 195 |
+
raise NotImplementedError
|
| 196 |
+
|
| 197 |
+
def __divmod__(self, other):
|
| 198 |
+
"""divmod(self, other): The pair (self // other, self % other).
|
| 199 |
+
|
| 200 |
+
Sometimes this can be computed faster than the pair of
|
| 201 |
+
operations.
|
| 202 |
+
"""
|
| 203 |
+
return (self // other, self % other)
|
| 204 |
+
|
| 205 |
+
def __rdivmod__(self, other):
|
| 206 |
+
"""divmod(other, self): The pair (self // other, self % other).
|
| 207 |
+
|
| 208 |
+
Sometimes this can be computed faster than the pair of
|
| 209 |
+
operations.
|
| 210 |
+
"""
|
| 211 |
+
return (other // self, other % self)
|
| 212 |
+
|
| 213 |
+
@abstractmethod
|
| 214 |
+
def __floordiv__(self, other):
|
| 215 |
+
"""self // other: The floor() of self/other."""
|
| 216 |
+
raise NotImplementedError
|
| 217 |
+
|
| 218 |
+
@abstractmethod
|
| 219 |
+
def __rfloordiv__(self, other):
|
| 220 |
+
"""other // self: The floor() of other/self."""
|
| 221 |
+
raise NotImplementedError
|
| 222 |
+
|
| 223 |
+
@abstractmethod
|
| 224 |
+
def __mod__(self, other):
|
| 225 |
+
"""self % other"""
|
| 226 |
+
raise NotImplementedError
|
| 227 |
+
|
| 228 |
+
@abstractmethod
|
| 229 |
+
def __rmod__(self, other):
|
| 230 |
+
"""other % self"""
|
| 231 |
+
raise NotImplementedError
|
| 232 |
+
|
| 233 |
+
@abstractmethod
|
| 234 |
+
def __lt__(self, other):
|
| 235 |
+
"""self < other
|
| 236 |
+
|
| 237 |
+
< on Reals defines a total ordering, except perhaps for NaN."""
|
| 238 |
+
raise NotImplementedError
|
| 239 |
+
|
| 240 |
+
@abstractmethod
|
| 241 |
+
def __le__(self, other):
|
| 242 |
+
"""self <= other"""
|
| 243 |
+
raise NotImplementedError
|
| 244 |
+
|
| 245 |
+
# Concrete implementations of Complex abstract methods.
|
| 246 |
+
def __complex__(self):
|
| 247 |
+
"""complex(self) == complex(float(self), 0)"""
|
| 248 |
+
return complex(float(self))
|
| 249 |
+
|
| 250 |
+
@property
|
| 251 |
+
def real(self):
|
| 252 |
+
"""Real numbers are their real component."""
|
| 253 |
+
return +self
|
| 254 |
+
|
| 255 |
+
@property
|
| 256 |
+
def imag(self):
|
| 257 |
+
"""Real numbers have no imaginary component."""
|
| 258 |
+
return 0
|
| 259 |
+
|
| 260 |
+
def conjugate(self):
|
| 261 |
+
"""Conjugate is a no-op for Reals."""
|
| 262 |
+
return +self
|
| 263 |
+
|
| 264 |
+
Real.register(float)
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
class Rational(Real):
|
| 268 |
+
""".numerator and .denominator should be in lowest terms."""
|
| 269 |
+
|
| 270 |
+
__slots__ = ()
|
| 271 |
+
|
| 272 |
+
@property
|
| 273 |
+
@abstractmethod
|
| 274 |
+
def numerator(self):
|
| 275 |
+
raise NotImplementedError
|
| 276 |
+
|
| 277 |
+
@property
|
| 278 |
+
@abstractmethod
|
| 279 |
+
def denominator(self):
|
| 280 |
+
raise NotImplementedError
|
| 281 |
+
|
| 282 |
+
# Concrete implementation of Real's conversion to float.
|
| 283 |
+
def __float__(self):
|
| 284 |
+
"""float(self) = self.numerator / self.denominator
|
| 285 |
+
|
| 286 |
+
It's important that this conversion use the integer's "true"
|
| 287 |
+
division rather than casting one side to float before dividing
|
| 288 |
+
so that ratios of huge integers convert without overflowing.
|
| 289 |
+
|
| 290 |
+
"""
|
| 291 |
+
return self.numerator / self.denominator
|
| 292 |
+
|
| 293 |
+
|
| 294 |
+
class Integral(Rational):
|
| 295 |
+
"""Integral adds a conversion to int and the bit-string operations."""
|
| 296 |
+
|
| 297 |
+
__slots__ = ()
|
| 298 |
+
|
| 299 |
+
@abstractmethod
|
| 300 |
+
def __int__(self):
|
| 301 |
+
"""int(self)"""
|
| 302 |
+
raise NotImplementedError
|
| 303 |
+
|
| 304 |
+
def __index__(self):
|
| 305 |
+
"""Called whenever an index is needed, such as in slicing"""
|
| 306 |
+
return int(self)
|
| 307 |
+
|
| 308 |
+
@abstractmethod
|
| 309 |
+
def __pow__(self, exponent, modulus=None):
|
| 310 |
+
"""self ** exponent % modulus, but maybe faster.
|
| 311 |
+
|
| 312 |
+
Accept the modulus argument if you want to support the
|
| 313 |
+
3-argument version of pow(). Raise a TypeError if exponent < 0
|
| 314 |
+
or any argument isn't Integral. Otherwise, just implement the
|
| 315 |
+
2-argument version described in Complex.
|
| 316 |
+
"""
|
| 317 |
+
raise NotImplementedError
|
| 318 |
+
|
| 319 |
+
@abstractmethod
|
| 320 |
+
def __lshift__(self, other):
|
| 321 |
+
"""self << other"""
|
| 322 |
+
raise NotImplementedError
|
| 323 |
+
|
| 324 |
+
@abstractmethod
|
| 325 |
+
def __rlshift__(self, other):
|
| 326 |
+
"""other << self"""
|
| 327 |
+
raise NotImplementedError
|
| 328 |
+
|
| 329 |
+
@abstractmethod
|
| 330 |
+
def __rshift__(self, other):
|
| 331 |
+
"""self >> other"""
|
| 332 |
+
raise NotImplementedError
|
| 333 |
+
|
| 334 |
+
@abstractmethod
|
| 335 |
+
def __rrshift__(self, other):
|
| 336 |
+
"""other >> self"""
|
| 337 |
+
raise NotImplementedError
|
| 338 |
+
|
| 339 |
+
@abstractmethod
|
| 340 |
+
def __and__(self, other):
|
| 341 |
+
"""self & other"""
|
| 342 |
+
raise NotImplementedError
|
| 343 |
+
|
| 344 |
+
@abstractmethod
|
| 345 |
+
def __rand__(self, other):
|
| 346 |
+
"""other & self"""
|
| 347 |
+
raise NotImplementedError
|
| 348 |
+
|
| 349 |
+
@abstractmethod
|
| 350 |
+
def __xor__(self, other):
|
| 351 |
+
"""self ^ other"""
|
| 352 |
+
raise NotImplementedError
|
| 353 |
+
|
| 354 |
+
@abstractmethod
|
| 355 |
+
def __rxor__(self, other):
|
| 356 |
+
"""other ^ self"""
|
| 357 |
+
raise NotImplementedError
|
| 358 |
+
|
| 359 |
+
@abstractmethod
|
| 360 |
+
def __or__(self, other):
|
| 361 |
+
"""self | other"""
|
| 362 |
+
raise NotImplementedError
|
| 363 |
+
|
| 364 |
+
@abstractmethod
|
| 365 |
+
def __ror__(self, other):
|
| 366 |
+
"""other | self"""
|
| 367 |
+
raise NotImplementedError
|
| 368 |
+
|
| 369 |
+
@abstractmethod
|
| 370 |
+
def __invert__(self):
|
| 371 |
+
"""~self"""
|
| 372 |
+
raise NotImplementedError
|
| 373 |
+
|
| 374 |
+
# Concrete implementations of Rational and Real abstract methods.
|
| 375 |
+
def __float__(self):
|
| 376 |
+
"""float(self) == float(int(self))"""
|
| 377 |
+
return float(int(self))
|
| 378 |
+
|
| 379 |
+
@property
|
| 380 |
+
def numerator(self):
|
| 381 |
+
"""Integers are their own numerators."""
|
| 382 |
+
return +self
|
| 383 |
+
|
| 384 |
+
@property
|
| 385 |
+
def denominator(self):
|
| 386 |
+
"""Integers have a denominator of 1."""
|
| 387 |
+
return 1
|
| 388 |
+
|
| 389 |
+
Integral.register(int)
|